has_many :through with class_name and foreign_key
I know this is an old question, but I just spent some time running into the same errors and finally figured it out. This is what I did:
class User < ActiveRecord::Base
has_many :listing_managers
has_many :managed_listings, through: :listing_managers, source: :listing
end
class Listing < ActiveRecord::Base
has_many :listing_managers
has_many :managers, through: :listing_managers, source: :user
end
class ListingManager < ActiveRecord::Base
belongs_to :listing
belongs_to :user
end
This is what the ListingManager join table looks like:
create_table :listing_managers do |t|
t.integer :listing_id
t.integer :user_id
end
Hope this helps future searchers.
The issue here is that in
has_many :managers, through: :listing_managers
ActiveRecord can infer that the name of the association on the join model (:listing_managers) because it has the same name as the has_many :through
association you're defining. That is, both listings and listing_mangers have many managers.
But that's not the case in your other association. There, a listing_manager has_many :listings
, but a user has_many :managed_listings
. So ActiveRecord is unable to infer the name of the association on ListingManager
that it should use.
This is what the :source
option is for (see http://guides.rubyonrails.org/association_basics.html#has-many-association-reference). So the correct declaration would be:
has_many :managed_listings, through: :listing_managers, source: :listing
(p.s. you don't actually need the :foreign_key
or :class_name
options on the other has_many :through
. You'd use those to define direct associations, and then all you need on a has_many :through
is to point to the correct association on the :through
model.)
i had several issues with my models, had to add the foreign key as well as the source and class name... this was the only workaround i found:
has_many :ticket_purchase_details, foreign_key: :ticket_purchase_id, source: :ticket_purchase_details, class_name: 'TicketPurchaseDetail'
has_many :details, through: :ticket_purchase_details, source: :ticket_purchase, class_name: 'TicketPurchaseDetail'