Block refactoring for group_by in Ruby on Rails

How can I rewrite this code so that it is completely dynamic, and I don’t need to use the case clause to manually list all possible @group values?

 # Grouping @group = params[:group] if !params[:group].blank? case @group when 'category_id' @ideas_grouped = @ideas.group_by { |i| i.category_id } when 'status_id' @ideas_grouped = @ideas.group_by { |i| i.status_id } when 'personal_bias' @ideas_grouped = @ideas.group_by { |i| i.personal_bias } when 'business_value' @ideas_grouped = @ideas.group_by { |i| i.business_value } end 
+4
source share
5 answers

If you do not need a white listing:

 @ideas_grouped = if (group = params[:group]).present? @ideas.group_by(&group.to_sym) end 

If you need a whitelist, can you call include? first include? (see Amar's answer), but to add something new, let me push it using a declarative approach ( Object#whitelist remains as an exercise for the reader, maybe comes from Ick ):

 @ideas_grouped = params[:group].whitelist(IdeaGroupers).maybe do |group| @ideas.group_by(&group.to_sym) end 
+2
source

You can use meta-programming The above code can be reorganized in one of the ways:

 if params[:group].present? && ["category_id","status_id","personal_bias","business_value"].include?(params[:group]) @ideas_grouped = @ideas.group_by { |i| i.send(params[:group]) } end 
+4
source

Try the following:

 @ideas_grouped = @ideas.group_by { |i| i.send(:"#{@group}")} if (@group = params[:group]) 
+2
source

What about:

 @group = params[:group] if !params[:group].blank? @ideas_grouped = ideas_hash.fetch(@group) def ideas_hash { 'category_id' => ideas_by_category_id, 'status_id' => ideas_by_status_id, 'personal_bias' => ideas_by_personal_bias 'business_value' => ideas_by_business_value } end def ideas_by_category_id @ideas.group_by { |i| i.category_id } end def ideas_by_status_id @ideas.group_by { |i| i.status_id } end def ideas_by_personal_bias @ideas.group_by { |i| i.personal_bias } end def ideas_by_business_value @ideas.group_by { |i| i.business_value } end 

I would also make ideas_hash and all other methods private.

+1
source

Well, the last time I touched Ruby was too far back, so I can't give you an example. As far as I understand your problem, you are doing a mapping (group -> accessor method). Thus, either you use the map object, or build a map function using lambda.

0
source

Source: https://habr.com/ru/post/1443612/


All Articles