I want to be able to show users who have liked a user’s post. I am going to provide a simple amount of information so this issue won’t get overwhelming.
I have three classes involved: User, Share and Opinion. Their models are set up likewise:
class User
has_many :opinions, foreign_key: "fan_id", dependent: :destroy
end
class Share
has_many :opinions, foreign_key: "like_id", dependent: :destroy
has_many :likes, through: :opinions
has_many :agreeables, foreign_key: "fan_id", class_name: "Opinion", dependent: :destroy
has_many :fans, through: :agreeables
end
class Opinion
belongs_to :fan, class_name: "User"
belongs_to :like, class_name: "Share"
end
In other words: like_id = share.id & fan_id = user.id
Then in my controller:
SharesController
def show
@share = Share.find(params[:id])
@shares = @share.fans.paginate(page: params[:page])
end
I click the link to share_path, it renders the page but with nothing on it. When I look at my SQL logs, I notice the problem:
It is not inner joining opinions correctly to have the rendered share (like_id) match up with the users who liked the share (fan_ids).
Let’s say the share.id was 11 and the current_user.id is 5. It’s query consists primarily of inner joining opinions to have the like_id AND fan_id = 11.
Any ideas on how I can fix this problem or an alternate method that is more practical?
Thanks for your help.
Edit
For any future readers, the solution was as followed:
class User
has_many :fans, foreign_key: "fan_id", class_name: "Opinion", dependent: :destroy
end
class Share
has_many :opinions, foreign_key: "like_id", dependent: :destroy
has_many :likes, through: :opinions
has_many :fans, through: :opinions
end
And the SharesController and Opinion model was left unchanged.
If you want to get all users who liked a
Share, the following code should be enough :In your controller,
@shares = @share.fans.paginate(page: params[:page])will return the list of users(fans)EDIT : As you’re not using conventional names (fan instead of User and like instead of Share), you might need to add more options like inverse_of and class_name, but I’m not really sure about that