Attempting to perform a has_many :through with a source association as a has_many :through currently fails:
class Author < ActiveRecord::Base
has_many :posts
has_many :categories, :through => :posts
has_many :recommended_posts, :through => :categories, :source => :posts
has_many :recommended_authors, :through => :recommended_posts, :source => :author
has_many :posts_of_recommended_authors, :through => :recommended_authors, :source => :posts
has_many :commenters, :through => :posts
end
class Post < ActiveRecord::Base
belongs_to :author
belongs_to :category
has_many :comments
has_many :commenters, :through => :comments, :source => :user
end
class Category < ActiveRecord::Base
has_many :posts
end
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :post
end
>> a=Author.create
=> #<Author:0x585c0b4 @new_record=false, @new_record_before_save=true, @errors=#<ActiveRecord::Errors:0x584ebd0 @base=#<
Author:0x585c0b4 ...>, @errors={}>, @attributes={"id"=>1}>
>> a.categories
=> []
>> a.recommended_posts
ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'categories.author_id' in 'where clause': SELECT posts.* FROM posts INNER JOIN categories ON posts.category_id = categories.id WHERE ((categories.author_id = 1))
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/connection_adapters/abstract_adapter.rb:122:in `log'
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/connection_adapters/mysql_adapter.rb:224:in `execute'
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/connection_adapters/mysql_adapter.rb:378:in `select'
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/connection_adapters/mysql_adapter.rb:215:in `select_all'
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/base.rb:424:in `find_by_sql'
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/base.rb:993:in `find_every'
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/base.rb:415:in `find'
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/associations/has_many_through_association.rb:97:in `find_target'
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/associations/association_proxy.rb:131:in `load_target'
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/associations/association_proxy.rb:122:in `method_missing'
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/associations/has_many_through_association.rb:90:in `method_missing'
from C:/Program Files/ruby/lib/ruby/1.8/irb.rb:298:in `output_value'
from C:/Program Files/ruby/lib/ruby/1.8/irb.rb:151:in `eval_input'
from C:/Program Files/ruby/lib/ruby/1.8/irb.rb:259:in `signal_status'
from C:/Program Files/ruby/lib/ruby/1.8/irb.rb:147:in `eval_input'
from C:/Program Files/ruby/lib/ruby/1.8/irb.rb:146:in `eval_input'
from C:/Program Files/ruby/lib/ruby/1.8/irb.rb:70:in `start'
from C:/Program Files/ruby/lib/ruby/1.8/irb.rb:69:in `catch'
from C:/Program Files/ruby/lib/ruby/1.8/irb.rb:69:in `start'
from C:/Program Files/ruby/bin/irb.bat:20>>
?> a.commenters
ActiveRecord::HasManyThroughSourceAssociationMacroError: Invalid source reflection macro :has_many :through for has_many :commenters, :through => :posts. Use :source to specify the source reflection.
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/reflection.rb:181:in `check_validity!'
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/associations/has_many_through_association.rb:6:in `initialize'
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/associations.rb:926:in `new'
from C:/Program Files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5263/lib/active_record/associations.rb:926:in `commenters'
from (irb):5
The proposed patch fixes the problem by allowing a has_many :through go through an arbitrary number of other has_many :through associations:
>> a=Author.create
=> #<Author:0x5854a44 @new_record=false, @new_record_before_save=true, @errors=#<ActiveRecord::Errors:0x5847560 @base=#<Author:0x5854a44 ...>, @errors={}>, @attributes={"id"=>1}>
>> a=Author.find(1)
=> #<Author:0x58435b4 @attributes={"id"=>"1"}>
>> a.categories
=> [#<Category:0x582ee0c @attributes={"id"=>"1"}>]
>> a.recommended_posts
=> [#<Post:0x582c6ac @attributes={"id"=>"1", "category_id"=>"1", "author_id"=>"1"}>, #<Post:0x582c670 @attributes={"id"=>"2", "category_id"=>"1", "author_id"=>"2"}>]
>> a.recommended_authors
=> [#<Author:0x582a03c @attributes={"id"=>"1"}>, #<Author:0x582a000 @attributes={"id"=>"2"}>]
>> a.commenters
=> [#<User:0x5811b7c @attributes={"id"=>"1"}>]