I have a Rails app where users can follow one another. I’ve just discovered a bug where a user can follow a person more than once.
If a user isn’t following someone, and opens the website in two different windows and clicks ‘follow’ in both windows, they are following the person twice.
In my controller I have a condition which I thought would prevent this from happening but it doesn’t work.
def follow
unless follows_arr.include?(params[:id])
@r = current_user.relationships.build
@r.friend_id = params[:id]
@r.save
end
end
follows_arr is an array of the IDs of the users the current user is following (current_user.relationships.map{|u| u[:friend_id]} ). params[:id] is the ID of the person the user is trying to follow.
For some reason, the second time someone clicks follow in this situation, the controller isn’t checking the updated database and two of the same ‘relationship’ are created.
Am I doing something wrong here? Is there another way to go about this?
Thanks!
The “real” answer to your problem is that those types of constraints should be checked in the model, not the controller (one may even argue it should be checked at database level, but Rails is just not made that way.
You can easily use the
validates_uniqueness_ofmethod in your model, e.g.:Which would indicate that each that the
followed_usermust be unique per follower.As for your original code, it is hard to say what is going wrong. It may depend on where the
follows_arrcomes from – maybe it contains some cached data, or you cached the variable yourself somewhere.But while it will be a useful learning experience figuring out why the original solution doesn’t work, for solving your original problem you’ll be better of putting the code in the model where it belongs.
If you need to do something in the controller, you can check like this: