def follows(follower, followed)
follow = Follows.where("follower = ? AND followed = ?", follower, followed)
if follow
true
else
false
end
end
Here is my view code:
<% if current_user.id == @user.id%>
<p>This is you!</p>
<% else %>
<% if follows(current_user.id, @user.id)%>
<p>You already follow <%= @user.username %>
<% else %>
<p><%= link_to "Follow!", follow_path(@user.id) %></p>
<% end %>
<% end %>
I want to check if a user follows another, so wrote this. It takes in two user ids, and queries the Database, and should return true when a match is found and false otherwise. But it always return true. Why is this?
Let's start with some style and design issues and end with the actual answer:
Models are singular by convention. Doing otherwise will only cause you more work. In this case, I would suggest Following as a suitable name, as in "a user has many followings".
Foreign keys should end with _id. Doing otherwise will only cause you more work. So follower_id and followed_id.
Methods that are intended to be used for their true/false nature ("query methods") should end with a ?, so follows? instead of follows,
Your if statement is redundant and can be safely removed once the condition does the right thing. In ruby, in the context of conditionals, we care more about whether things evaluate to true/false than whether they are literally true or false. This means that anything other than nil or false will be "truthy".
The fact that your method depends entirely on information known to User objects indicates that it would be better to hang it off of those objects, for instance current_user.follows? other_user.
You are duplicating behavior that would already be provided to you by using associations.
Finally, taking all of these things into consideration, the answer:
class User < ActiveRecord::Base
has_many :followings, :class_name => 'Following', :foreign_key => 'followed_id'
has_many :followers, :through => 'followings'
def follows?(other)
other.followed_by? self
end
def followed_by?(other)
followers.include? other
end
end
NB: The use of the followed_by? method here is a use of double dispatch that prevents the (minor) Law of Demeter violation of one user knowing directly about the state of another user's followers. Rather, the first user object asks the second user object a direct question ("Are you followed by me?") and bases the result off of the answer. (It is also likely to be a useful method in and of itself.)
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