自加入HABTM协会的范围
Posted
技术标签:
【中文标题】自加入HABTM协会的范围【英文标题】:Scope for Self-joining HABTM Association 【发布时间】:2012-01-20 01:30:12 【问题描述】:在Ruby 1.9.2
上使用Rails 3.1.3
,我有:
class User < ActiveRecord::Base
has_and_belongs_to_many :states
end
class State < ActiveRecord::Base
has_and_belongs_to_many :users
end
User
与许多 State
s 相关联,State
与许多 User
s 相关联。给定一个User
,我想找到在她的任何州的所有其他User
s。
我试过了:
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
想法?
谢谢。
更新 12/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)
它不是特别优雅,但它正在工作。您必须为“传入”User
引用 users
引用别名,以便您可以将此范围与其他范围链接,例如:
scope :active, where(active => true)
User.in_states_of(current_user).active
欢迎提出任何改进建议。
【问题讨论】:
【参考方案1】:这是有效的:
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)
它不是特别优雅,但它正在工作。您必须为“传入”User
引用 users
别名,以便您可以将此范围与其他范围链接,例如:
scope :active, where(active => true)
User.in_states_of(current_user).active
欢迎提出任何改进建议。
【讨论】:
以上是关于自加入HABTM协会的范围的主要内容,如果未能解决你的问题,请参考以下文章