Rails habtm 和查找没有关联的记录
我有 2 个模型:
class User < ActiveRecord::Base
has_and_belongs_to_many :groups
end
class Group < ActiveRecord::Base
has_and_belongs_to_many :users
end
我想创建一个返回不属于任何组的用户的范围(这很重要 - 对于效率和链接范围的能力)。 经过多次尝试,我未能执行方法而不是作用域,这使得 User.all
上的 collect
很丑陋而且......不正确。
有什么帮助吗?
也许对于第二个问题: 我设法创建一个范围,返回属于任何给定组的用户(以 id 数组形式给出)。
scope :in_groups, lambda { |g|
{
:joins => :groups,
:conditions => {:groups => {:id => g}},
:select => "DISTINCT `users`.*" # kill duplicates
}
}
它可以更好/更漂亮吗? (使用 Rails 3.0.9)
I have 2 models:
class User < ActiveRecord::Base
has_and_belongs_to_many :groups
end
class Group < ActiveRecord::Base
has_and_belongs_to_many :users
end
I want to make a scope (that's important - for efficiency and for ability to chain scopes) that returns Users that doesn't belong to ANY Groups.
After many tries, I failed in doing a method instead of scope, which makes collect
on User.all
which is ugly and.. not right.
Any help?
And maybe for 2nd question:
I managed to make a scope that returns Users who belongs to any of given groups (given as an array of id's).
scope :in_groups, lambda { |g|
{
:joins => :groups,
:conditions => {:groups => {:id => g}},
:select => "DISTINCT `users`.*" # kill duplicates
}
}
Can it be better/prettier?
(Using Rails 3.0.9)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
根据命名约定,您的隐式联接表将被命名为
groups_users
。在您的数据库中确认一次。假设是:在较新的 Rails 版本中:
对于较旧的 Rails 版本:
Your implicit join table would have been named
groups_users
based on naming conventions. Confirm it once in your db. Assuming it is:In newer Rails version:
For older Rails versions:
如果您通过(更灵活的)关联从 HABTM 转换为 has_many,那么您可以使用如下内容:
If you convert from HABTM to has_many through (more flexible) association, then you can use something like this:
在Rails >= 5中,有left_outer_joins,组合使用新的(ish)
.where()
语法,使作用域更具可读性:In Rails >= 5, there is left_outer_joins, combined with the new(ish)
.where()
syntax, makes the scope a bit more readable: