На has_many есть несколько постов и тем: through, но я не нашел ни одной, которая бы описывала конкретно то, что я пытаюсь сделать.
У меня есть модель User и модель Friendship. У пользователя есть много пользователей, которые следуют за ними, а также много подписчиков. Это обычная модель Twitter.
Для данного пользователя я хочу настроить отношения Active Record, которые возвращают реальных пользователей, которые следуют за пользователем, и этот пользователь является последователем.
Это отношения, которые я настроил:
class User < ActiveRecord::Base
has_many :following, :class_name => 'User', :through => :friendships, :foreign_key => 'user_id'
has_many :followers, :class_name => 'User', :through => :friendships, :foreign_key => 'friend_id'
end
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :following, :class_name => 'User', :foreign_key => 'friend_id'
belongs_to :follower, :class_name => 'User', :foreign_key => 'user_id'
end
Следующие отношения работают - они генерируют следующее соединение:
SELECT `users`.* FROM `users` INNER JOIN `friendships` ON `users`.id = `friendships`.friend_id WHERE ((`friendships`.user_id = 1))
Все великолепно.
Однако отношения Подписчик не работают. Я попробовал несколько вариантов, но большинство, похоже, возвращает тот же набор результатов, что и ниже.
Мне нужно настроить соединение следующим образом, чтобы получить правильный набор результатов.
SELECT `users`.* FROM `users` INNER JOIN `friendships` ON `users`.id = `friendships`.user_id WHERE ((`friendships`.friend_id = 1));
Куда я иду не так?
Я могу настроить это с помощью опции finder_sql на has_many, но, похоже, должен быть лучший способ.
has_many :followers, :class_name => 'User', :finder_sql => 'SELECT `users`.* FROM `users` INNER JOIN `friendships` ON `users`.id = `friendships`.user_id WHERE ((`friendships`.friend_id = #{ id }))'
Спасибо!
Я немного продвинулся и, наконец, установил отношения, разбив отношения на две части, как было показано в этом ответе: Самостоятельная ссылка has_many: сквозная с настроенным: проблема первичного ключа
# FOLLOWING
has_many :friendships_to, :foreign_key => 'user_id', :class_name => 'Friendship'
has_many :following, :through => :friendships_to, :class_name => 'User'
# FOLLOWERS
has_many :friendships_from, :foreign_key => 'friend_id', :class_name => 'Friendship'
has_many :followers, :through => :friendships_from, :class_name => 'User'
Однако, хотя было возможно иметь однострочную версию отношения для следования
has_many :following, :class_name => 'User', :through => :friendships, :foreign_key => 'user_id'
Я все еще не мог заставить его работать на последователей. Все еще интересуетесь, как это можно сделать?