How to present interchangeable columns

I'm not quite sure how to express this, but is there a good way to implement a table where columns are essentially interchangeable?

Example: you have the Users model and you want to allow two users to be friends. The obvious way for me would be to have a table containing two columns ("friend1" and "friend2"), each of which contains a key for the user. This makes it inconvenient to say something like "user1 and user2 friends" because you need to check "(friend1 = user1 AND friend2 = user2) OR (friend1 = user2 AND friend2 = user1)". This will work, but it seems inconvenient to me that every time you want to get something from this table, you look in both columns. Is there a more elegant way to do this?

+5
source share
3 answers

- , . Twitter, Facebook, . , , 2 :

1)

select *
from friendships 
where (friend1 = 123 and friend2 = 456) OR (friend2 = 123 and friend1 = 456)

2) user_id friend1 user_id friend2, . , .

+3

, , . , "friendlyId" : friendlyId . .

, user1 user2 :

select friendshipId
from friends
group by friendshipId
having sum(case when name = user1 then 1 else 0 end) > 0 and
       sum(case when name = user2 then 1 else 0 end) > 0

, , , - ..

+1

You can do has_many through or has_and_belongs_to_many http://guides.rubyonrails.org/association_basics.html

Any way you want the join table to link your user models.

eg

class User < ActiveRecord::Base
  has_many :followings
  has_many :followers, :through => :followings, :class_name => "User"
  has_many :followees, :through => :followings, :class_name => "User"
end


class Following < ActiveRecord::Base 
  # fields: follower_id followee_id (person being followed)
  belongs_to :follower, :class_name => "User"
  belongs_to :followee, :class_name => "User"
end

the same as the user has a lot: users, or should I use a different way for a friends-based social network?

0
source

All Articles