代码之家  ›  专栏  ›  技术社区  ›  gnarf

用动态编程重构?

  •  0
  • gnarf  · 技术社区  · 17 年前

    我这里有一段代码,我真的需要一些重构方面的帮助。我需要不同的方法在rails的表单中添加关系数据。代码取自 http://railscasts.com/episodes/75-complex-forms-part-3 ,我的问题是我需要有材料模型和答案模型的方法。所以我需要两次完全相同的代码,用“答案”替换“材料”。

    这似乎应该用一些动态规划来解决?但我对此毫无经验。

    这是如何解决的?

    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
    
    2 回复  |  直到 17 年前
        1
  •  5
  •   srboisvert    17 年前

    您可能还想看看这个网站:

    http://refactormycode.com/

        2
  •  1
  •   tvanfosson    17 年前

    如果我没弄错的话,你想用同样的方法 answers 至于 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