Rails ActiveRecord Scope that is the “opposite” of another scope, or is users that “lack” a property

荒凉一梦 提交于 2019-12-08 17:09:44

问题


I have a model for user.rb, in which I define a scope for admins, which is users that have the role of admin through a permissions table.

has_many :permissions
has_many :roles, :through => :permissions

The scope works like this:

scope :admins, joins(:permissions).merge(Permission.admin_permissions)

I'd also like to make a scope called non-admins or something like that, which is all users that do NOT have the admin role.

What's the easiest way to do this?


回答1:


An easy way, which would not be performant for a lot of users:

admin_user_ids  = User.admins.map(&:id)
non_admin_users = User.all.reject { |u| admin_user_ids.include?(u.id) }



回答2:


If you want to have an inverted SQL query, you will have to do it yourself manually. There is no built-in ActiveRecord solution.

scope :admins, joins(:permissions).merge(Permission.where("permissions.admin = true"))
scope :non_admins, joins(:permissions).merge(Permission.where("permissions.admin = false"))

If there are a lot of scopes or they are complex, consider excluding them by id:

User.where("id not in (?)", User.admins.pluck(:id))

# or if you are already using admin records
admins = User.admins
User.where("id not in (?)", admins.map(&:id))

Depending on number of rows and complexity of the original query, this could be slower or faster than the previous way.



来源:https://stackoverflow.com/questions/14406669/rails-activerecord-scope-that-is-the-opposite-of-another-scope-or-is-users-th

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!