1

Мне нужно создать пользовательскую модель Friendship (user1_id, user2_id), которая соединяет пользователей.Howto структура рельсов модель дружеских друзей?

Я хотел бы избежать создания двух записей Friendship для каждого пользователя/друга, поскольку дружба идет в обе стороны.

Как бы вы это сделать так, имея несколько простой

# User.rb 
has_many :friendships 
has_many :friends, :through => :friendships, :class_name => "User" 

EDIT Мое решение было зеркало записи:

class Friendship < ActiveRecord::Base 
    belongs_to :user1 
    belongs_to :user2 

    after_create :create_mirror! 
    after_destroy :destroy_mirror! 

    validate :does_not_exist 

    def mirror_record 
     Friendship.where(:user1_id => user2.id, :user2_id => user1.id).first 
    end 

    private 

    def does_not_exist 
     errors.add(:base, 'already exists') if Friendship.where(:user1_id => user1.id, :user2_id => user2.id) rescue nil 
    end 

    def create_mirror! 
     Friendship.create(:user1 => user2, :user2 => user1) 
    end 

    def destroy_mirror! 
     mirror_record.destroy if mirror_record 
    end 
end 

ответ

0

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

class User 
    has_many :friendships 
    has_many :invited, :through => :friendships, :source => :friend 
    has_many :invited_by, :through => :inverse_friendships, :source => :user 

    def friends 
    self.invited + self.invited_by 
    end 

class Friendships 
    belongs_to :user 
    belongs_to :friend, :class_name => "User", :foreign_key => "friend_id" 

Таким образом, в контроллерах, вы можете написать что-то вроде user.friends принести всем друзьям.

+0

Теперь я отпущу то, что я хочу сделать, это кошмарная без зеркальных записей, которая является лучшим и единственным решением. –

0

Вы должны только одна запись на дружбу. Класс Friendship просто имеет два атрибута, каждый из которых указывает на одного из друзей.

class Friendship 
    belongs_to user1, :class_name => "User" 
    belongs_to user2, :class_name => "User" 

... и ваш стол ...

friendship_id | user1_id | user2_id 
----------------------------------- 

В Rails 2.x это называется "имеет и принадлежит многим" (HABTM).

Я считаю, вы должны явно указать имена классов для каждого из belongs_to заявления, поскольку они указывают на один и тот же тип родительской записи (а User), и как таковой вы не можете назвать оба поля user - вы должны каким-то образом отличать их от имени.

+0

это делает модель «Дружба», но отношения «Пользователь» HABTM все еще не работают. Вы не можете называть 'User.first.friends << User.last' или даже' User.first.friends', поскольку ': source' может иметь только одно значение:': game1' или ': game2'. –

+0

Исправьте меня, если я ошибаюсь, но это не 'has_many: дружба' и' has_many: friends,: through =>: дружба' избыточна? Может быть, мне придется развернуть тестовый проект, чтобы посмотреть, что произойдет. – jefflunt