Если я вас правильно понял, вы хотите использовать те же методы для answers
, что и для materials
, но с дублированием наименьшего кода. Способ сделать это - абстрагировать некоторые частные методы, которые будут работать для 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