0

I have a model Friendship where :friend_id is also a foreign key as :user_id

friendships id | user_id | friend_id I'm aware that validating the uniqueness of the two fields would be something like this

validates :user_id, :uniqueness => {:scope => :friend_id}

But is there a way to validate

user_id = 1, friend_id = 3
user_id = 3, friend_id = 1 

so that only user_id = 1, friend_id = 3 is stored?

  • why do you wan't to dissallow the second case? Isn't that a scenario where user 20 adds user 10 back? – davegson Jul 04 '14 at 07:05
  • which database u r using?? – Gagan Gami Jul 04 '14 at 07:10
  • I would also suggest that you rename your model to `Friendship`, as you don't create & manage a `Friend`, rather a friendship between users. – davegson Jul 04 '14 at 07:11
  • in your case 1 you mean that data should not be repeat?? there is duplicate – Gagan Gami Jul 04 '14 at 07:17
  • I would avoid disabling second case. To be honest, this is how you should create friendship models - always both connections for each friendship, so you can easily load them (e.g. joins, includes) – konole Jul 04 '14 at 09:28

1 Answers1

1

Join Model

Looks like you're using a join model with Rails - as mentioned in the comments, you'll want to change this to friendship (not friend).

Rails has two types of join mechanism - has_many :through and has_and_belongs_to_many - both allow you to associate many-to-many records, like this:

#app/models/user.rb
Class User < ActiveRecord::Base
   has_many :friendships
   has_many :friends, through: :friendships
end

#app/models/friendship.rb
Class Friendship < ActiveRecord::Base
   belongs_to :friend, class: "User", foreign_key: "friend_id"
   belongs_to :user
end

#friendships
id | user_id | friend_id | created_at | updated_at

I would recommend you have a friendship model (as opposed to a model-less HABTM setup), because HMT allows you to add extra data, such as created_at, updated_at, permissions, etc)


Self Referential

I would also use a self-referential model. This will allow you to keep a single model (for User), and then call @user.friends without an issue.

Whether my above association definitions are correct is another matter; this is how you'd want to set them up.

--

Validation

In terms of validating your associations, I believe you'll be able to use indexes in your DB. This is used often for HABTM tables -

#Migration

# Adding the index can massively speed up join tables. Don't use the
# unique if you allow duplicates.
add_index(:friendships, [:user_id, :friend_id], :unique => true)

This will work for your original case, but not for the second

Community
  • 1
  • 1
Richard Peck
  • 76,116
  • 9
  • 93
  • 147