Ассоциация Rails HABTM через две таблицы соединений

У меня есть следующие модели:

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

Как я могу объявить, что FriendGroup has_and_belongs_to_many :friends through :friendships?

Я хотел бы иметь FriendGroup.friend_ids, поэтому в форме я могу просто установить поле 'friend_group[friend_ids][]' и просто вызвать FriendGroup.create(params[:friend_group]) без какой-либо дополнительной логики.


person RocketR    schedule 28.10.2010    source источник


Ответы (3)


Я смущен тем, что вы пытаетесь сделать с FriendGroups.

Ваша базовая дружба моделируется следующим образом:

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

Вы хотите массово создавать записи о дружбе между всеми пользователями, которых вы передаете? Вероятно, это какая-то проблема с перестановками. Не то, для чего вам понадобится другая модель. Может быть, метод класса на Friendship, например interconnect(user_ids).

Если вы хотите найти группы пользователей, которые дружат друг с другом, это звучит так, как будто вы изучаете теорию графов и возможность подключения.

ИЗМЕНИТЬ:

В случае, когда FriendGroups являются просто общими контейнерами друзей с прикрепленным именем, я бы сделал что-то вроде этого:

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

Я бы, вероятно, вложил FriendGroups в Users, а FriendGroups accept_nested_attributes_for FriendGroupings. Я бы сделал это в контроллере FriendGroup и в представлении для FriendGroup позволил бы пользователю установить имя группы, а затем дал бы им флажки для каждого из своих друзей, чтобы поместить их в группу. Для каждого друга они выбирают создание новой группы друзей между группой друзей и пользователем. Это должно дать вам то, что вы хотите.

person Adam Tanner    schedule 28.10.2010
comment
Вот как это работает на месте. Когда пользователь добавляет друзей, создается Friendship объектов. Затем он может перейти к своему списку друзей, выбрать некоторых из них и создать имя FriendGroup (например, «Семья», «Одноклассники» и т. д.). Вопрос в том, какой пользователь должен отправить для создания группы: user_ids или friendship_ids. С friendship_ids в модели все просто, но мне кажется более логичным и последовательным, что вы фактически создаете группу пользователей, а не группу отношений. Поэтому я хотел бы сохранить friendship_ids невидимым для пользователя. - person RocketR; 29.10.2010
comment
Я отредактировал ответ, чтобы иметь дело с FriendGroups. Я думаю, что это больше, чем то, что вы ищете. - person Adam Tanner; 29.10.2010

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

person marcgg    schedule 28.10.2010

Что ж, я нашел не однострочное, а двухстрочное решение, которое выглядит достаточно элегантно:

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)}
person RocketR    schedule 28.10.2010