С Rails 3.1.3
на Ruby 1.9.2
, у меня есть:
class User < ActiveRecord::Base
has_and_belongs_to_many :states
end
class State < ActiveRecord::Base
has_and_belongs_to_many :users
end
A User
ассоциируется со многими State
с, а State
со многими User
с. Учитывая User
, я хочу найти всех других User
, которые находятся в любом из ее состояний.
Я пытался:
class User < ActiveRecord::Base
scope :in_state, lambda { |states| joins(:states).where(:states => states) }
end
User.in_state(current_user.states).all
С этой ошибкой (отформатированной для удобства чтения):
Mysql2::Error: Not unique table/alias: 'states_users':
SELECT COUNT(*)
FROM `users`
INNER JOIN `states_users` ON `states_users`.`user_id` = `users`.`id`
INNER JOIN `states` ON `states`.`id` = `states_users`.`state_id`
LEFT OUTER JOIN states_users on users.id = states_users.user_id AND states_users.state_id IS NULL
WHERE `states`.`id` IN (8)
Я понимаю, что мне нужен какой-то способ для псевдонима одной из states_users
ссылок, но я не могу понять, как это сделать с scope
.
Вот SQL, который я бы написал:
SELECT u2.*
FROM users u
INNER JOIN states_users su ON su.user_id = u.id
INNER JOIN states s ON s.id = su.state_id
INNER JOIN states_users su2 ON s.id = su2.state_id
INNER JOIN users u2 ON u2.id = su2.user_id
WHERE u.id = 771
Мысли
Спасибо.
ОБНОВЛЕНИЕ 14/14/2011 @ 10:48 AM:
Вот что работает:
scope :in_states_of, lambda { |user|
joins('INNER JOIN states_users su ON su.user_id = users.id ' +
'INNER JOIN states s ON s.id = su.state_id ' +
'INNER JOIN states_users su2 ON s.id = su2.state_id ' +
'INNER JOIN users u ON u.id = su2.user_id').
where("u.id = ?", user.id) }
User.in_states_of(current_user)
Это не особо элегантно, но работает. Вам необходимо присвоить псевдоним users
для «входящих» User
, чтобы вы могли связать эту область с другими, такими как:
scope :active, where(active => true)
User.in_states_of(current_user).active
Любые предложения по улучшению приветствуются.