views:

27

answers:

3

I have the following models:

class Friendship < ActiveRecord::Base
  belongs_to :user
  belongs_to :friend, :class_name => "User", :foreign_key => :friend_id
  has_and_belongs_to_many :friend_groups
end

class FriendGroup < ActiveRecord::Base
  has_and_belongs_to_many :friendships
end

How can I declare that FriendGroup has_and_belongs_to_many :friends through :friendships?

I would like to have FriendGroup.friend_ids, so in the form I can just set a field 'friend_group[friend_ids][]' and just call FriendGroup.create(params[:friend_group]) without any additional logic.

A: 

class FriendGroup < ActiveRecord::Base has_and_belongs_to_many :friends, :through => :friendgroups end

marcgg
A: 

Well, I found not the one-line, but two-line solution which looks elegant enough:

class FriendGroup < ActiveRecord::Base
...
  attr_accessor :friend_ids
  before_create {|fg| fg.friendships = Friendship.find_all_by_user_id_and_friend_id(fg.user_id, fg.friend_ids)}
RocketR
A: 

I'm confused on what you are trying to do with FriendGroups.

Your basic Friendship is modeled as:

class Friendship < ActiveRecord::Base
  belongs_to :user
  belongs_to :friend, :class_name => "User"
end

class User < ActiveRecord::Base
  has_many :friendships
  has_many :friends, :through => :friendships
end

Are you looking to mass create Friendship records between all the Users that you pass in? That's probably some sort of permutations problem. Not something you would need another model for. Maybe a class method on Friendship like interconnect(user_ids).

If you're wanting to find groups of Users that are all friends of each other that sounds like you're getting into Graph Theory and connectivity.

EDIT:

In the case of FriendGroups just being generic containers of friends with a name attached I would do something like this:

class User < ActiveRecord::Base
  has_many :friend_groupings
  has_many :friend_groups
  has_many :friendships
  has_many :friends, :through => :friendships
end

class FriendGrouping < ActiveRecord::Base
  belongs_to :friend_group
  belongs_to :friend
end

class FriendGroup < ActiveRecord::Base
  has_many :friend_groupings
  has_many :friends, :class_name => "User", :through => :friend_groupings
  belongs_to :user

  validates_presence_of :name # Name of FriendGroup
end

I would probably nest FriendGroups under Users, and have FriendGroups accept_nested_attributes_for FriendGroupings. I would do this in the FriendGroup controller and in the view for the FriendGroup allow the user to set the name of the group and then give them checkboxes for each of their friends to put in the group. For each friend they select create a new FriendGrouping between the FriendGroup and the User. That should get you what you want.

Adam Tanner
Here's how it works on site. When user adds friends, `Friendship` objects are created. Then he can go to his friend list, select some of them and create a named `FriendGroup` (e.g Family, Classmates etc).The question is what user should submit to create a group: `user_ids` or `friendship_ids`. With `friendship_ids` everything is easy in model, but it looks to me more logical and consistent that you are actually creating a group of users, not a group of relations. So I would like to keep `friendship_ids` invisible to user.
RocketR
I edited the answer to deal with FriendGroups. I think that is more so what you are looking for.
Adam Tanner
Nice, thank you.
RocketR