0

I have built a user and friend relationship model but the problem is that with those associations I can friend myself. I have successfully suppressed it in my views and controller, but logically it should be suppressed in the model because I could still create the friendship from the console which I want to avoid.

User model

has_many :user_friendships
has_many :friends, through: :user_friendships,
                conditions: { user_friendships: { state: 'accepted' } }

User_friendship model

belongs_to :user
belongs_to :friend, class_name: 'User', foreign_key: 'friend_id'

Everything else is working perfectly like adding, blocking, deleting, requesting a friend the only problem with my model is that I can also friend myself which I want to avoid.

Anurag Agarwal
  • 303
  • 2
  • 4

3 Answers3

0

This issue is a little problematic because we want to remain RESTful, separate the different tasks (MVC,) and take into account of weird race conditions (Thread Safety.)

Try using validations#exclusions (http://guides.rubyonrails.org/active_record_validations_callbacks.html#exclusion)

class ApplicationController < ActionController::Base
  ...
  before_filter do |c|
    User.current_user = User.find(c.session[:user]) unless c.session[:user].nil?  
  end
  ...
end

class User < ActiveRecord::Base
  ...
  cattr_accessor :current_user
  ...
end

class Friends < ActiveRecord::Base
  ...
  validates :friend_id, :exclusion => { :in => %w(User.current_user.id),
  :message => "I don't think you really want to friend yourself" } 
  ...
end

If you want to be safe, please refer to (http://nhw.pl/wp/2011/11/30/passing-current-user-id-to-rails-models)

Disclaimer:

  • I wrote this possible solution without testing it (aka pulled it out of the thin air with little reference)
  • I have not thread with Ruby on Rails.
Jeff
  • 109
  • 2
0

You probably want to throw in a validation

Such as

validate :cannot_friend_self

def cannot_friend_self
  current_user.id != friend.id
end

This code may not be exactly what you want, but should point you in the right direction.

Full guide here http://guides.rubyonrails.org/active_record_validations_callbacks.html#custom-methods

muttonlamb
  • 6,341
  • 3
  • 26
  • 35
  • current_user is not accessible in models (see this [answer](http://stackoverflow.com/a/1574569/1065703) ) – Martin M May 31 '13 at 06:54
0

Add a validation to UserFriendship:

validate :cannot_friend_self

def cannot_friend_self
  errors.add(:friend_id, "cannot friend self") unless user_id != friend_id
end
Martin M
  • 8,430
  • 2
  • 35
  • 53
  • Well I actually solved it just before you added it, but anyways thanks for the help. I have been trying similar things but when i added an error message it worked and i was so much relieved of after spending hours on it :D – Anurag Agarwal May 31 '13 at 08:11