我怎样才能重构这些常见的控制器方法?

时间:2013-01-04 04:04:33

标签: ruby-on-rails ruby refactoring

我有一些非常相似的控制器方法,我想知道重构它们的最佳方法是什么。首先想到的是以某种方式将两个块传递给辅助方法,但我不知道该怎么做。

def action_a
  if @last_updated.nil?
    @variable_a = @stuff_a
  else
    @variable_a = (@stuff_a.select{ |item| item.updated_at > @last_updated }
  end
end

def action_b
  if @last_updated.nil?
    @variable_b = @stuff_b.some_method
  else
    @variable_b = @stuff_b.some_method.select{ |stuff| item.updated_at > @last_updated }
  end
end

似乎我一直在检查@last_updated是否为零(我在@last_updated中设置before_filter实例变量。如果我能以某种方式传递if内的内容1}}作为一个块和else中的内容作为另一个块,那么我可以删除if @last_updated.nil?重复吗?

在许多方法中实现这一目标的最佳方法是什么?

更新

在我指定@stuff_a@stuff_b的地方,他们总是返回一个数组(因为我使用.select)。

3 个答案:

答案 0 :(得分:3)

看看这个。它是DRYer,应该产生相同的结果。

def action_a
  do_the_processing :"@variable_a", @stuff_a
end

def action_b
  do_the_processing :"@variable_b", @stuff_b.some_method
end

private
def do_the_processing var_name, collection
  if @last_updated.nil?
    instance_variable_set var_name, collection
  else
    instance_variable_set var_name, collection.select{ |item| item.updated_at > @last_updated }
  end
end

更新

这是两个块的方法(只是为了好玩)(使用1.9的stabby lambda语法)

def action_a
  check_last_updated is_nil: -> { @variable_a = @stuff_a },
                     is_not_nil: -> { @variable_a = (@stuff_a.select{ |item| item.updated_at > @last_updated } }
end

def action_b
  check_last_updated is_nil: -> { @variable_b = @stuff_b.some_method },
                     is_not_nil: -> { @variable_b = @stuff_b.some_method.select{ |stuff| item.updated_at > @last_updated } }
end

private
def check_last_updated blocks = {}
  if @last_updated.nil?
    blocks[:is_nil].try(:call)
  else
    blocks[:is_not_nil].try(:call)
  end
end

答案 1 :(得分:1)

您需要在单独的def块中提取您的条件,并在以后使用它:

def select_updates a
  @last_updated.nil? ? a : a.select{ |item| item.updated_at > @last_updated }
end
def action_a; @variable_a = select_updates(@stuff_a) end
def action_b; @variable_b = select_updates(@stuff_b.some_method) end

答案 2 :(得分:0)

我可以看到,你可以做以下事情

每个

都有两个范围

前:

class Stuff < ActiveRecord::Base
  scope :updated_at, lambda {|updated_date|
    {:conditions => "updated_at > #{updated_date}"}
  }
end


class Item < ActiveRecord::Base
  scope :updated_at, lambda {|updated_date|
    {:conditions => "updated_at > #{updated_date}"}
  }
end
控制器中的

执行此操作

def action_a
  @variable_a = update_method(@stuff_a)
end

def action_b
  @variable_b = update_method(@stuff_b)
end

private
def update_method(obj)
  result = nil
  if @last_updated.nil?
    result = obj.some_method 
  else    
    result = obj.some_method.updated_at(@last_updated) 
  end  
  result 
end

HTH