Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactoring a switched block statement for group_by in Ruby on Rails

How can I rewrite this code so it's completely dynamic, and I don't have to use the case clause to manually list all possible values of @group?

# 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
like image 404
Tom Söderlund Avatar asked Jan 15 '23 03:01

Tom Söderlund


2 Answers

You can use some sort of meta programming Above code can be refactored in one of the way is

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
like image 51
Amar Avatar answered Jan 17 '23 16:01

Amar


If you need no white-listing:

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

If you need white-listing you may call include? first (see Amar's answer), but to add something new, let me push it with a declarative approach (Object#whitelist is left 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
like image 36
tokland Avatar answered Jan 17 '23 16:01

tokland