user has many :users, or must I use another way for a friend based social network?
Asked Answered
P

3

2

I'm creating a little social network in Rails, where people can add eachother as a friend. I have created a model called 'user', which contains, e-mail, strong md5 hash with salt of password etc.

How do I create something like an option to add another user as a friend? Is it possible to have something like has_many_and_belongs_to :user in the user model? So a user has many users and belongs to many users. Or should I use another way, like adding a friendship model which has user1s_id:integer and user2s_id:integer?

Pushy answered 15/2, 2010 at 20:21 Comment(2)
You mean "user which contains, e-mail, hash of password" right??Tetragonal
Yep, md5'd and with a salt, so it's unpassworddictionaryable =DPushy
M
2

I would suggest that a user has many relationships, this would leave you free to add new types of relationships in the future.

So you start with a "one user to another user" relationship table (minimally, just two IDs) and then in the future you could add a "one user to a group" relationship table (once you've created groups of course!)

Martin answered 15/2, 2010 at 20:30 Comment(3)
So you actually mean the 'adding a friendship model which has user1s_id:integer and user2s_id:integer' way?Pushy
Thanks, I always did this in PHP, but I asked this question to check if there is a more Railsy way. So far as I understand, it's the hard way @Lorylose suggested but this one is easier.Pushy
What Bigwave describes in not necessarily what I said was the hard way. This solution describing a polymorphic relationship that allows for more detail. It's not exactly clear. But it looks like a description for a unidirectional relationship (ie: As in I might be friends with you, but that doesn't mean you are friends with me).Lorylose
L
3

Essentially you want a join model that joins users to users. But you'll have to use more descriptive terms for Rails.

Twitter doesn't use Rails, but here's how their user associations might work in Rails using Twitter's terminology. Note: Twitter doesn't require bidirectional following (ie just because a user follows another, doesn't mean that second user follows the first)

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

Forced bidirectional friendship (like Facebook enforces that I cannot be friends with you, unless you are a friends with me) will take a little more work. You will either need to manage reciprocal entries with callbacks, or use custom finder SQL. Using custom finder SQL means that ActiveRecord probably won't be able to manage associations for you.

Lorylose answered 15/2, 2010 at 20:35 Comment(1)
Looks like I'm wrong on the Twitter using Rails issue. I assumed the news about their switch to Scala meant they were giving up Rails entirely.Lorylose
M
2

I would suggest that a user has many relationships, this would leave you free to add new types of relationships in the future.

So you start with a "one user to another user" relationship table (minimally, just two IDs) and then in the future you could add a "one user to a group" relationship table (once you've created groups of course!)

Martin answered 15/2, 2010 at 20:30 Comment(3)
So you actually mean the 'adding a friendship model which has user1s_id:integer and user2s_id:integer' way?Pushy
Thanks, I always did this in PHP, but I asked this question to check if there is a more Railsy way. So far as I understand, it's the hard way @Lorylose suggested but this one is easier.Pushy
What Bigwave describes in not necessarily what I said was the hard way. This solution describing a polymorphic relationship that allows for more detail. It's not exactly clear. But it looks like a description for a unidirectional relationship (ie: As in I might be friends with you, but that doesn't mean you are friends with me).Lorylose
C
2

I'd suggest using the friendship model because db-wise you'll need a join table either way, but making that table explicit will allow you to store more details about the relationship (e.g. "friend" or "family", date added, ...)

Condolent answered 15/2, 2010 at 20:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.