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