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?
Scopes are used to assign complex ActiveRecord queries into customized methods using Ruby on Rails. Inside your models, you can define a scope as a new method that returns a lambda function for calling queries you're probably used to using inside your controllers.
1 What is Active Record? Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database.
Scopes are custom queries that you define inside your Rails models with the scope method. Every scope takes two arguments: A name, which you use to call this scope in your code. A lambda, which implements the query.
Returns a new relation, which is the result of filtering the current relation according to the conditions in the arguments.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With