4

如何重写此代码,使其完全动态,并且我不必使用该case子句手动列出 的所有可能值@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
4

5 回答 5

4

您可以使用某种元编程 上面的代码可以通过一种方式进行重构

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
于 2012-11-02T09:19:19.617 回答
2

试试这个:

@ideas_grouped = @ideas.group_by { |i| i.send(:"#{@group}")} if (@group = params[:group])
于 2012-11-02T09:24:53.407 回答
2

如果您不需要白名单:

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

如果您需要白名单,您可以include?先致电(请参阅 Amar 的回答),但要添加新内容,让我用声明性方法推动它(Object#whitelist留给读者作为练习,maybe来自Ick):

@ideas_grouped = params[:group].whitelist(IdeaGroupers).maybe do |group|
  @ideas.group_by(&group.to_sym)
end
于 2012-11-02T09:54:28.823 回答
1

关于什么 :

@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

我还将ideas_hash 和所有其他方法设为私有。

于 2014-11-07T23:39:27.160 回答
0

好的,我上次接触 Ruby 的时间太久远了,所以我不能给你举个例子。据我了解您的问题,您正在那里进行映射(组-> 访问器方法)。因此,要么使用映射对象,要么使用 lambda 构建映射函数。

于 2012-11-02T09:55:41.560 回答