Rails: ActiveRecord::HasManyThroughSourceAssociationNotFoundError: Could not find the source association(s)

一笑奈何 提交于 2019-11-30 11:50:24

User should be defined like this:

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, :source => :card

end

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.

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.

def change
    create_table :signatures do |t|
        t.integer :signer_id
        t.integer :card_id
        t.boolean :signed,    :default => false
        t.text :message

        t.timestamps
    end
end

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.

class Signature < ActiveRecord::Base
    belongs_to :card
    belongs_to :signer, :class_name => "User"
end

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.

class User < ActiveRecord::Base
    has_many :signatures, :foreign_key => "signer_id"
    has_many :signed_cards, :through => :signatures, :source => :card 
end

Finally, the Card has many signatures (once again necessary) and many signers through signatures and the foreign_key for the signer of signer_id.

class Card < ActiveRecord::Base
    has_many :signatures
    has_many :signers, :through => :signatures, :foreign_key => 'signer_id'
end

Hopefully, this will help others having similar issues.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!