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?
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With