0

ここには、リファクタリングに役立つコードがあります。Rails のフォームにリレーショナル データを追加するには、さまざまな方法が必要です。コードはhttp://railscasts.com/episodes/75-complex-forms-part-3から取得されます。私の問題は、Material モデルと Answer モデルの両方のメソッドが必要なことです。したがって、「材料」を「回答」に置き換えたまったく同じコードが2回必要です。

これは、動的プログラミングで解決する必要があるようです。しかし、私はそれについてまったく経験がありません。

これはどのように解決されますか?

after_update :save_materials
after_update :save_answers  

def new_material_attributes=(material_attributes)
  material_attributes.each do |attributes|
    materials.build(attributes)
  end
end

def existing_material_attributes=(material_attributes)
  materials.reject(&:new_record?).each do |material|
    attributes = material_attributes[material.id.to_s]
    if attributes
      material.attributes = attributes
    else
      materials.delete(material)
    end
  end
end

def save_materials
  materials.each do |material|
    material.save(false)
  end
end
4

2 に答える 2

5

このサイトもご覧ください。

http://refactormycode.com/

于 2008-12-26T14:43:33.387 に答える
1

私があなたを正しく理解していれば、 に対して と同じメソッドが必要ですanswersmaterials、最小限のコードを複製する必要があります。answersこれを行う方法は、 or のいずれかで機能するいくつかのプライベート メソッドを抽象化materialsし、それらのモデルに固有のメソッドから適切なモデルでそれらを呼び出すことです。以下にサンプルをあげました。save_これらのメソッドは十分に短いため、メソッドを抽象化してもあまり節約できないと感じたため、メソッドについては何もしていないことに注意してください。

after_update :save_materials
after_update :save_answers  

// Public methods

def new_material_attributes=(material_attributes)
  self.new_with_attributes(materials, material_attributes)
end

def new_answer_attributes=(answer_attributes)
  self.new_with_attributes(answers, answer_attributes)
end

def existing_material_attributes=(material_attributes)
  self.existing_with_attributes(materials, material_attributes)
end

def existing_answer_attributes=(answer_attributes)
  self.existing_with_attributes(answers, answer_attributes)
end

def save_materials
  materials.each do |material|
    material.save(false)
  end
end

def save_answers
  answers.each do |answer|
     answer.save(false)
  end
end

// Private methods    

private
def new_with_atttributes(thing,attributes)
    attributes.each do |attribute|
       thing.build(attribute)
    end
end

def existing_with_attributes=(things, attributes)
  things.reject(&:new_record?).each do |thing|
    attrs = attributes[thing.id.to_s]
    if attrs
      thing.attributes = attrs
    else
      things.delete(thing)
    end
  end
end
于 2008-12-26T15:11:43.173 に答える