Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 用动态编程重构?_Ruby On Rails_Ruby_Dynamic_Metaprogramming - Fatal编程技术网

Ruby on rails 用动态编程重构?

Ruby on rails 用动态编程重构?,ruby-on-rails,ruby,dynamic,metaprogramming,Ruby On Rails,Ruby,Dynamic,Metaprogramming,我这里有一段代码,我真的需要一些重构方面的帮助。我需要不同的方法在rails的表单中添加关系数据。代码取自,我的问题是我需要材料模型和答案模型的方法。所以我需要两次完全相同的代码,用“答案”替换“材料” 这似乎应该用一些动态规划来解决?但我对此毫无经验 这是如何解决的 after_update :save_materials after_update :save_answers def new_material_attributes=(material_attributes) mate

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

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

这是如何解决的

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

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


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


如果我理解正确,您希望对
答案采用与
材料相同的方法,但复制最少的代码。实现这一点的方法是抽象一些私有方法,这些方法将用于
答案
材料
,并使用特定于这些模型的方法中的适当模型调用它们。我在下面给出了一个示例。请注意,我没有使用
save\uu
方法做任何事情,因为我觉得它们足够短,所以对它们进行抽象实际上节省不了多少

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

如果我理解正确,您希望对
答案
采用与
材料
相同的方法,但复制最少的代码。实现这一点的方法是抽象一些私有方法,这些方法将用于
答案
材料
,并使用特定于这些模型的方法中的适当模型调用它们。我在下面给出了一个示例。请注意,我没有使用
save\uu
方法做任何事情,因为我觉得它们足够短,所以对它们进行抽象实际上节省不了多少

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