Reverse has_many with polymorphism

associations, polymorphism, ruby-on-rails

Solution

Figured it out. Took a look at a sample project Michael Hartl made and noticed that the correct way to do this is to specify not only a relationship table (in this case follows) but also a reverse relationship table (which I called reverse follows).

    has_many    :follows,
                        :dependent => :destroy

    has_many    :followed_projects,
                        :through => :follows,
                        :source => :followable,
                        :source_type => "Project"

    has_many    :followed_users,
                        :through => :follows,
                        :source => :followable,
                        :source_type => "User"

    has_many    :reverse_follows,
                        :as => :followable,
                        :foreign_key => :followable_id,
                        :class_name => "Follow"

    has_many    :followers,
                        :through => :reverse_follows,
                        :source => :user

Hope this helps some people out down the line!

Problem

I have two models: Users and Projects. The idea is that Users can follow both projects AND other users. Naturally, Users and Projects are part of a polymorphic "followable" type. Now, using the user model, I'd like to get three things: ``` user.followed_users user.followed_projects user.followers ``` The first two work fine; It's the third that I'm having trouble with. This is sort of a reverse lookup where the foreign key becomes the "followable_id" column in the follows table, but no matter how I model it, I can't get the query to run correctly. User Model ``` has_many :follows, :dependent => :destroy has_many :followed_projects, :through => :follows, :source => :followable, :source_type => "Project" has_many :followed_users, :through => :follows, :source => :followable, :source_type => "User" has_many :followers, :through => :follows, :as => :followable, :foreign_key => "followable", :source => :user, :class_name => "User" ``` Follow Model ``` class Follow < ActiveRecord::Base belongs_to :followable, :polymorphic => true belongs_to :user end ``` My follows table has: user_id followable_id followable_type Whenever I run the query I get: ``` SELECT `users`.* FROM `users` INNER JOIN `follows` ON `users`.`id` = `follows`.`user_id` WHERE `follows`.`user_id` = 7 ``` where it should be "followable_id = 7 AND followable_type = 'User", not "user_id = 7" Any thoughts?

Original source