Specify the currently captured records in the model class method

I have a class method where I want to change the records that are currently captured by the ActiveRecord::Relation object. But I don't know how to access the current scope in a class method. self does not do this.

Example:

 class User < ActiveRecord::Base ... def self.modify_those_records #thought implicitly #to_a would be called on currently grabbed records but doesn't work temp_users_to_a = to_a ... end end 

I would use it as follows:

 User.some_scope.modify_those_records 

So User.some_scope will return to me ActiveRecord::Relation , which contains a bunch of User entries. Then I want to change these entries in this class method and then return them.

The problem is this: I don’t know how to explicitly refer to “this group of records” inside the class method.

+6
source share
3 answers

You can use current_scope :

 def self.modify_those_records current_scope.each do |user| user.do_something! end end 

If you want to order users based on their administrator rights, you better use ActiveRecord:

 scope :order_admins_first, order('CASE WHEN is_admin = true THEN 0 ELSE 1 END, id') User.some_scope.order_admins_first 

This code means that there is a logical column is_admin in the users table.

+4
source

I would say that combining a scope with each and an instance method is easier to understand than a class method. And as a bonus, it’s easier to test, because you can test all stages separately:

So instead of User.some_scope.modify_those_records I would do something like:

 User.some_scope.each(&:modify) 

and implement the instance method:

 # in user.rb def modify # whatever needs to be done end 
+2
source

If you want to change the order of records, it is best to add to the sort field (if you don’t have one) and sort by it.

 User.some_scope.order(name: :asc).order(is_admin: :desc) 
+1
source

All Articles