Reputation: 1482
I have a user table in my rails application and the application uses many where
conditions for this model throughout the application in many controller methods.
Now i have to add an extra attribute for the where condition.
is there a way to do the following and how? instead of adding the extra attribute to all the where condition used in the entire application can i write a custom where
to the user model so the condition will be pre-added to the where
in entire application for the user model.
i found out the source for the where
def where(opts = :chain, *rest)
if :chain == opts
WhereChain.new(spawn)
elsif opts.blank?
self
else
spawn.where!(opts, *rest)
end
end
my where condition in the controller methods now:
User.where(:status => true, :country => "IN")
this condition and similar conditions are used in many methods in application and i want to get the user who has not :deactivated
.
i can make changes to all where condition like
User.where(:status => true, :country => "IN", :deactivated => false)
instead i thought of writing a custom where that precheck :deactivated => false
Upvotes: 1
Views: 467
Reputation: 2699
Default Scope:
class User < ActiveRecord::Base
default_scope -> { where(deactivated: false) }
end
You can use default_scope
.
Now, whenever you query User
, automatically the default scope query will get appended.
For more details on default_scope
, please refer:
https://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html#method-i-default_scope
If there are usecases that prevent you from using default_scope, then you can use custom scopes or unscope the default scope.
Unscoping:
You can unscope in Project
model if you want to remove the default scope.
belongs_to :user, ->{ unscope(where: :deactivated) }
Or you can fetch all user and then unscope
project.users.unscoped
Custom Scope:
class User < ActiveRecord::Base
scope :deactivated, ->(deactivated = false) { where(deactivated: deactivated) }
end
Now, to make use of that scope, you can query like this:
User.deactivated.where(:status => true, :country => "IN")
For reference: https://api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html#method-i-scope
Upvotes: 3