Я хочу реализовать систему друзей пользователя в своем приложении, поэтому я нашел решение для решения проблем с рельсами очень красивым, идея состоит в том, чтобы создать две строки в the Friendships table
: первая строка за приглашение отправителя, а второй для приемникалучший способ реализовать модель дружбы в рельсах
связь между пользователями является установкой с has_many
ассоциации, как это:
has_many :friendships
has_many :friends, :through => :friendships, :conditions => "status = 'accepted'"
методом для принятия пользователя как друг, как это:
метода# Accept a friend request.
def self.accept(user, friend)
transaction do
accepted_at = Time.now
accept_one_side(user, friend, accepted_at)
accept_one_side(friend, user, accepted_at)
end
end
accept_one_side() является:
# Update the db with one side of an accepted friendship request.
def self.accept_one_side(user, friend, accepted_at)
request = find_by_user_id_and_friend_id(user, friend)
request.status = 'accepted'
request.accepted_at = accepted_at
request.save!
end
это имеет то преимущество, что мы можем выполнить одну просьбы, чтобы получить все друг из двух сторон (либо пользователь, который послал приглашение или друг, который послал она)
, но я думаю, что это имеет недостаток, если, например, в действительности есть 500 друзей, приятельств таблица содержит «500X2 = 1000» линии
второе решение, чтобы сделать обратную связь с has_many through
нравится объясняется в RailsCast #163 Self-Referential Association:
has_many :friendships
has_many :friends, :through => :friendships
has_many :inverse_friendships, :class_name => "Friendship", :foreign_key => "friend_id"
has_many :inverse_friends, :through => :inverse_friendships, :source => :user
, но здесь, если вы хотите получить все друг для пользователя вы должны использовать два запрос на что:
user.friends
user.inverse_friends
, который не является лучшим способом на всех, если вам есть огромная таблица друзей ...
Что я хочу знать, это лучший метод из двух выше, то есть способ его оптимизировать? если есть еще один супер метод, я буду благодарен
Привет @spickermann спасибо за ответ, что вы думаете о размере таблицы, которая будет X2? – medBo
Двойной размер стола не будет проблемой в течение длительного времени. У меня есть таблица дружбы в производственной базе данных, которая содержит более 4 миллионов записей и даже не принимает 200 МБ на диске. – spickermann
спасибо, ваш комментарий успокаивает меня, еще один вопрос о вашем коде, пожалуйста, что вы подразумеваете под after_save: define_friendship – medBo