Has_many: via ,: source ,: source_type, returning an empty array

I got the Manager model and SoccerTeam . The manager owns many football teams; Also, the manager can comment on football teams and can comment on other managers:

manager.rb

 # Soccer teams the manager owns has_many :soccer_teams, :dependent => :restrict # Comments the manager has made on soccer teams or other managers has_many :reviews, :class_name => "Comment", :foreign_key => :author_id, :dependent => :destroy # Comments the manager has received by other managers has_many :comments, :as => :commentable, :dependent => :destroy # Soccer teams that have received a comment by the manager has_many :observed_teams, :through => :comments, :source => :commentable, :source_type => "SoccerTeam" 

soccer_team.rb

 # The manager that owns the team belongs_to :manager # Comments received by managers has_many :comments, :as => :commentable, :dependent => :destroy # Managers that have reviewed the team has_many :observers, :through => :comments, :source => :author, :class_name => "Manager" 

comment.rb

 belongs_to :commentable, :polymorphic => true belongs_to :author, :class_name => Manager 

Now, if I have a manager commenting on SoccerTeam, I expect to find:

  • A Comment object in manager.reviews and in soccer_team.comments
  • SoccerTeam object in manager.observed_teams
  • Manager object in soccer_team.observers

While everything works well for the first and third points, when I call manager.observed_teams , I always get an empty array. To get a list of football teams, the manager commented on what I need to use:

 manager.reviews.collect{ |review| Kernel.const_get(review.commentable_type).find(review.commentable_id) if review.commentable_type == "SoccerTeam" } 

What is ugly. I expect a simple manager.observed_teams to work ... why is it not?

Edit

I went further, understanding why this does not work. In fact, genrated SQL:

 SELECT "soccer_teams".* FROM "soccer_teams" INNER JOIN "comments" ON "soccer_teams".id = "soccer_teams".commentable_id AND "comments".commentable_type = 'SoccerTeam' WHERE (("comments".commentable_id = 1) AND ("comments".commentable_type = 'Manager')) 

For now, I want it to be:

 SELECT "soccer_teams".* FROM "soccer_teams" INNER JOIN "comments" ON "soccer_teams".id = "comments".commentable_id AND "comments".commentable_type = 'SoccerTeam' WHERE ("comments".author_id = 1) 

So the question is simple: how to get this request? (A heuristic attempt with :foreign_key ans :as , as expected, did not solve the problem!).

+7
source share
1 answer

I think you just used the wrong association for observed_teams . Instead

 has_many :observed_teams, :through => :comments, :source => :commentable, :source_type => "SoccerTeam" 

Try the following:

 has_many :observed_teams, :through => :reviews, :source => :commentable, :source_type => "SoccerTeam" 

Besides,

 has_many :reviews, :class_name => :comment, :foreign_key => :author_id, :dependent => :destroy 

:comment should be 'Comment'

and in

 has_many :comments, :as => commentable, :dependent => :destroy 

commmentable should be :commmentable

+13
source

All Articles