自加入 HABTM 协会的范围

发布于 2024-12-21 03:47:03 字数 2175 浏览 2 评论 0原文

使用 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 相关联,以及一个包含许多UserState。给定一个用户,我想找到处于其任何状态的所有其他用户

我尝试过:

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 引用之一添加别名,但我不知道如何使用 范围

这是我要写的 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)

它不是特别优雅,但它有效。您必须为“传入”Userusers 引用起别名,以便您可以将此范围与其他范围链接起来,例如:

scope :active, where(active => true)

User.in_states_of(current_user).active

任何改进建议都将受到欢迎。

With Rails 3.1.3 on Ruby 1.9.2, I have:

class User < ActiveRecord::Base
  has_and_belongs_to_many :states
end

class State < ActiveRecord::Base
  has_and_belongs_to_many :users
end

A User is associated with many States, and a State with many Users. Given a User, I want to find all other Users who are in any of her states.

I tried:

class User < ActiveRecord::Base
  scope :in_state, lambda { |states| joins(:states).where(:states => states) }
end

User.in_state(current_user.states).all

With this error (formatted for readability):

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)

I realize I need some way to alias one of the states_users references, but I'm at a loss for figuring out how to do this with scope.

Here's the SQL I would write:

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

Thoughts?

Thanks.

UPDATE 12/14/2011 @ 10:48 AM:

Here's what's working:

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)

It's not particularly elegant, but it's working. You have to alias the users reference for the "incoming" User so you can chain this scope with others, such as:

scope :active, where(active => true)

User.in_states_of(current_user).active

Any suggestions for improvement would be most welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

差↓一点笑了 2024-12-28 03:47:03

这是有效的:

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)

它不是特别优雅,但它有效。您必须为“传入”Userusers 引用起别名,以便您可以将此范围与其他范围链接起来,例如:

scope :active, where(active => true)

User.in_states_of(current_user).active

任何改进建议都将受到欢迎。

Here's what's working:

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)

It's not particularly elegant, but it's working. You have to alias the users reference for the "incoming" User so you can chain this scope with others, such as:

scope :active, where(active => true)

User.in_states_of(current_user).active

Any suggestions for improvement would be most welcome.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文