0

非常によく似たコントローラーメソッドがいくつかあり、それらをリファクタリングするための最良の方法は何でしょうか。最初に頭に浮かぶのは、どういうわけか2つのブロックをヘルパーメソッドに渡すことですが、それを行う方法もわかりません。

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常にnilかどうかをチェックしているようです(@last_updatedインスタンス変数をブロックとして設定しますbefore_filter。どういうわけか、内部のものをifブロックとして渡し、内部のものを別のブロックとして渡すことができれば、重複elseを削除できますか?if @last_updated.nil?

多くの方法でこれを達成するための最良の方法は何ですか?

アップデート

とを指定する@stuff_a@stuff_b、常に配列が返されます(を使用しているため.select)。

4

3 に答える 3

3

これを見てください。それはドライヤーであり、同じ結果をもたらすはずです。

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

アップデート

そして、これが2つのブロックアプローチです(楽しみのために)(1.9のスタビーラムダ構文を使用します)

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
于 2013-01-04T04:10:18.077 に答える
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
于 2013-01-04T10:17:19.723 に答える
0

私が見ることができるように、あなたは次のことをすることができます

それぞれに2つのスコープがあります

元:

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

于 2013-01-04T04:42:53.057 に答える