Rails:ActiveRecord :: HasManyThroughSourceAssociationNotFoundError:找不到源关联
我有以下代码(有些简化...
create_table :signatures do |t|
t.integer :signer_id
t.integer :card_id
t.timestamps
end
模型看起来像...
class Signature < ActiveRecord::Base
belongs_to :card
belongs_to :user
end
class Card < ActiveRecord::Base
has_many :signatures
has_many :signers, :through => :signatures, :foreign_key => "card_id"
end
class User < ActiveRecord::Base
has_many :sent_cards, :class_name => "Card", :foreign_key => "sender_id"
has_many :received_cards, :class_name => "Card", :foreign_key => "recipient_id"
has_many :signatures
has_many :signed_cards, :through => :signatures, :foreign_key => "signer_id"
end
我使用rails控制台看到以下错误...
ruby-1.9.2-p0 > u15.signed_cards
ActiveRecord::HasManyThroughSourceAssociationNotFoundError: Could not find the source association(s) :signed_card or :signed_cards in model Signature. Try 'has_many :signed_cards, :through => :signatures, :source => <name>'. Is it one of :card or :user?
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/reflection.rb:517:in `check_validity!'
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations/association.rb:27:in `initialize'
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations/collection_association.rb:24:in `initialize'
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations.rb:164:in `new'
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations.rb:164:in `association'
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations/builder/association.rb:41:in `block in define_readers'
from (irb):11
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.1.0/lib/rails/commands/console.rb:45:in `start'
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.1.0/lib/rails/commands/console.rb:8:in `start'
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.1.0/lib/rails/commands.rb:40:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
当我添加 source => :card 时,我得到了同样的结果/:user
(我认为在这种情况下应该是:card)。
有什么想法我在这里做错了吗?
因为我想清理一个 几件事。迁移与之前的版本保持一致。我现在 看到 SQL 错误(见下文),在签名中找不到 user_id。我 不想这么说,但大多数时候我都在我认为的任何地方输入 :foreign_key 他们可能无济于事。
class Signature < ActiveRecord::Base
belongs_to :card
belongs_to :signer, :class_name => "User"
end
class Card < ActiveRecord::Base
# Correct
has_many :signatures
has_many :signers, :through => :signatures, :source => :user
end
class User < ActiveRecord::Base
# Wrong!
has_many :signatures, :foreign_key => "signer_id"
has_many :signed_cards, :through => :signatures, :source => :card
end
出现错误(减去堆栈跟踪)时,
ruby-1.9.2-p0 > u15.signed_cards
Card Load (0.5ms) SELECT "cards".* FROM "cards" INNER JOIN "signatures" ON "cards"."id" = "signatures"."card_id" WHERE "signatures"."user_id" = 15 ORDER BY cards.created_at DESC
SQLite3::SQLException: no such column: signatures.user_id: SELECT "cards".* FROM "cards" INNER JOIN "signatures" ON "cards"."id" = "signatures"."card_id" WHERE "signatures"."user_id" = 15 ORDER BY cards.created_at DESC
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: signatures.user_id: SELECT "cards".* FROM "cards" INNER JOIN "signatures" ON "cards"."id" = "signatures"."card_id" WHERE "signatures"."user_id" = 15 ORDER BY cards.created_at DESC
Card.signers
按预期返回一个空数组。
仍在寻找有关此问题的一些帮助。我无法以简单、直接的方式找到很多解释,其中您没有使用相同的名称(即您需要一个foreign_key和source。
I have the following code (somewhat simplified ...
create_table :signatures do |t|
t.integer :signer_id
t.integer :card_id
t.timestamps
end
With the models looking like ...
class Signature < ActiveRecord::Base
belongs_to :card
belongs_to :user
end
class Card < ActiveRecord::Base
has_many :signatures
has_many :signers, :through => :signatures, :foreign_key => "card_id"
end
class User < ActiveRecord::Base
has_many :sent_cards, :class_name => "Card", :foreign_key => "sender_id"
has_many :received_cards, :class_name => "Card", :foreign_key => "recipient_id"
has_many :signatures
has_many :signed_cards, :through => :signatures, :foreign_key => "signer_id"
end
I see the following error using the rails console ...
ruby-1.9.2-p0 > u15.signed_cards
ActiveRecord::HasManyThroughSourceAssociationNotFoundError: Could not find the source association(s) :signed_card or :signed_cards in model Signature. Try 'has_many :signed_cards, :through => :signatures, :source => <name>'. Is it one of :card or :user?
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/reflection.rb:517:in `check_validity!'
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations/association.rb:27:in `initialize'
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations/collection_association.rb:24:in `initialize'
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations.rb:164:in `new'
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations.rb:164:in `association'
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations/builder/association.rb:41:in `block in define_readers'
from (irb):11
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.1.0/lib/rails/commands/console.rb:45:in `start'
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.1.0/lib/rails/commands/console.rb:8:in `start'
from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.1.0/lib/rails/commands.rb:40:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
I get the same thing when I do add the source => :card/:user
(should be :card in this case I believe).
Any ideas what I'm doing wrong here?
Showing a partial solution because I wanted to clean up a
few things. The migration remained the same as the previous version. I'm now
seeing a SQL error (see below) where it can't find user_id in Signature. I
hate to say it, but mostly I've been putting in :foreign_key whereever I think
they might help to no avail.
class Signature < ActiveRecord::Base
belongs_to :card
belongs_to :signer, :class_name => "User"
end
class Card < ActiveRecord::Base
# Correct
has_many :signatures
has_many :signers, :through => :signatures, :source => :user
end
class User < ActiveRecord::Base
# Wrong!
has_many :signatures, :foreign_key => "signer_id"
has_many :signed_cards, :through => :signatures, :source => :card
end
With the error (minus stack trace)
ruby-1.9.2-p0 > u15.signed_cards
Card Load (0.5ms) SELECT "cards".* FROM "cards" INNER JOIN "signatures" ON "cards"."id" = "signatures"."card_id" WHERE "signatures"."user_id" = 15 ORDER BY cards.created_at DESC
SQLite3::SQLException: no such column: signatures.user_id: SELECT "cards".* FROM "cards" INNER JOIN "signatures" ON "cards"."id" = "signatures"."card_id" WHERE "signatures"."user_id" = 15 ORDER BY cards.created_at DESC
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: signatures.user_id: SELECT "cards".* FROM "cards" INNER JOIN "signatures" ON "cards"."id" = "signatures"."card_id" WHERE "signatures"."user_id" = 15 ORDER BY cards.created_at DESC
Card.signers
returns an empty array as expected.
Still looking for some help on this one. I haven't been able to locate much in the way of simple, straightforward explanations of this where you're not using the same names (i.e. you need a foreign_key and source.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
User 应如下定义:
当您的关联名称与 :through 中使用的名称不同时,您必须定义 source 参数。如果您查看异常消息,它会明确要求您执行此操作。
User should be defined like this:
When your association name is different than the name used at the :through you have to define the source parameter. If you look at the exception message it explicitly asks you to do it.
好吧,既然我在这方面遇到了很大的困难,我想向大家展示一下
最终版本看起来像。我经历如此艰难的一个重要原因
弄清楚这一点,事实是 Rails 控制台似乎并不
当我做出更改时正确地重新加载内容。我没有意识到这一点,直到我
放弃了一晚,第二天早上回来,案子已经解决了
前一天晚上工作不工作,而不工作的情况则工作。
迁移是相同的,但为了完整起见,我将重复它。
Signature 类有两个belongs_to 和card 的情况是
通常会在示例中显示,并且签名者是用户类型。
用户有很多签名(即使您不直接使用它们也是必要的)
dmanysigned_cards 通过带有卡源的签名(告诉Rails
signed_cards 属于哪个类类型。
最后,该卡有许多签名(再次必要)和许多签名者
通过signer_id 的签名者的签名和foreign_key。
希望这能帮助其他有类似问题的人。
OK, since I had such a hard time with this, I wanted to show everyone what the
final version looked like. A good part of the reason I had such a hard time
firguring this out, was the fact that the rails console didn't seem to be
reloading things correctly as I made changes. I didn't realize this until I
gave up one night, came back the next morning and the case that had been
working the previous night wasn't and the case that wasn't working was.
The migration is the same, but I'll repeat it for completeness sake.
The Signature class has the two belongs_to with card being the case that
normally gets shown in the examples and the signer being of type user.
The User has many signatures (necessary even if you don't use them directly)
an dmany signed_cards through signatures with a source of card (telling Rails
which class type the signed_cards are.
Finally, the Card has many signatures (once again necessary) and many signers
through signatures and the foreign_key for the signer of signer_id.
Hopefully, this will help others having similar issues.