在我的Rails API中,我的子模型中有以下代码:
before_create :delete_error_from_values, :check_errors, :update_child_if_exists
def delete_error_from_values
@new_error = self.values["error"]
@values = self.values.tap { |hs| hs.delete("error") }
end
def update_child_if_exists
conditions = {type: self.type, parent_id: self.parent_id}
if existing_child = Child.find_by(conditions)
new_values = existing_child.values.reverse_merge!(@values)
hash = {:values => new_values}
existing_child.update_attributes(hash)
end
end
def check_errors
if self.type == "error"
conditions = {type: self.type, parent_id: self.parent_id}
if existing_child = Child.find_by(conditions)
bd_errors = existing_child.error_summary
bd_errors[@new_error] = bd_errors[@new_error].to_i + 1
hash = {:error_summary => bd_errors}
existing_child.update_attributes(hash)
else
self.error_summary = {@new_error => 1}
end
end
end
这就像预期的那样工作,除了一个小细节:如果按类型和parent_id的记录已经存在,则会更新子项,但它也会被创建。如何重构它以停止创建?
我试图包含return false
,但如果我这样做,更新不会成功。
我希望有类似 find_or_create_by
的东西,但我不确定在这种情况下如何使用它。
也许你可以用以下方法重构你的代码:
def create
@parent = Parent.find(params[:parent_id])
existing_child = Child.where(type: child_params[:type], parent_id:
child_params[:parent_id]).first
if existing_child.present?
existing_child.update_attributes(attribute: value_1)
else
@child = @parent.child.build(child_params)
end
#other saving related code goes here.
end
这只是一个基本的例子。尝试创建单独的实例方法来保持 Contrller DRY 。:)