我不确定如何在ruby中更干净地编写这段代码?唯一不同的是迭代器。
if items.respond_to?(:find_each)
items.find_each do |item|
output_item(csv, item)
end
else
items.each do |item|
output_item(csv, item)
end
end
答案 0 :(得分:5)
您可以使用Object#send
动态调用方法:
method = items.respond_to?(:find_each) ? :find_each : :each
items.send(method) do |item|
output_item(csv, item)
end
答案 1 :(得分:2)
我想你可以这样做:
method = items.respond_to?(:find_each) ? :find_each : :each
items.send(method) { |item| output_item(csv, item) }
答案 2 :(得分:0)
我试图让这个分支的意图更清晰一点:
iterator = items.is_a?(ActiveRecord::Relation) ? :find_each : :each
items.send(iterator) { |item| output_item(csv, item) }
选择哪个迭代器是一个实现细节,可能会使我的业务逻辑更难理解。让我们将迭代逻辑提取到一个单独的方法中。如果总业务逻辑是单线程,那么这种提取的好处是值得商榷的。如果原始方法更长,它将增加更多清晰度。
def iterate(relation_or_array, *args, &block)
iterator = relation_or_array.is_a?(ActiveRecord::Relation) ? :find_each : :each
relation_or_array.send(iterator, *args, &block)
end
# main logic
iterate(items) { |item| output_item(csv, item) }
既然我们没有使用原始方法,我会扩展三元if
以提高可读性。
def iterate(relation_or_array, *args, &block)
if relation_or_array.is_a? ActiveRecord::Relation
relation_or_array.find_each(*args, &block)
else
relation_or_array.each(*args, &block)
end
end
# main logic
iterate(items) { |item| output_item(csv, item) }