How to rewrite rails group_by class method as scop

2019-08-12 04:30发布

问题:

I would like to rewrite my class method as a scope.

class Team

 def self.grouped
   self.all.group_by { |e| e.type }.map { |k, v| { k => v.group_by { |e| e.sub_type } } }
 end

end

How would I write as a scope?

class Team

 #  scope :grouped ??

end

回答1:

You cannot write this as a scope. Scopes in Rails act on ActiveRecord::Relation objects and are supposed to generate SQL queries that run against the database.

But the group_by method is called on the array after the data was received from the database.

You will always have to load the data from the database first, before you can group it with group_by.

You could write your own nested_group_by method on Array:

class Array
  def nested_grouped_by(group_1, group_2)
    group_by { |e| e.send(group_1) }.
      map { |k, v| { k => v.group_by { |e| e.send(group_2) } } }
  end
end

That could be used like this:

Team.all.nested_grouped_by(:type, :subtype)

Note the all that force the scope to actually load the data from the database and returns an array.