我的成员控制器中有以下代码:
def update
@member.phone_numbers.destroy_all
respond_to do |format|
if @member.update(member_params)
format.html { redirect_to @member, notice: 'Member was successfully updated' }
else
format.html { render action: 'edit' }
end
end
end
我必须在更新成员之前删除 phone_numbers 中的现有记录,因为必须再次插入电话号码(因为可能的订单更改和其他原因,但确实如此)没关系)。
问题是:它有效,但如果成员无法更新,则所有电话号码都将被删除。
如果 @ member.update 失败,可以采取哪些措施来避免此问题?
答案 0 :(得分:2)
您可以考虑将电话号码标记为销毁,而不是实际删除它们。
@member.phone_numbers.map(&:mark_for_destruction)
然后,当你执行@ member.update时,它应该同时更新和销毁相关的电话号码。以下是#mark_for_destruction的API:http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html#method-i-mark_for_destruction
否则,您可以查看设置事务块。 API很好地解释了这一点:http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html
答案 1 :(得分:1)
将其包装到一个帮助器方法中,该方法将语句包装到事务中并从控制器调用:
# Member Model
def delete_phone_numbers_and_update(params)
Member.transaction do
phone_numbers.destroy_all
update(params)
end
end
# Controller
def update
respond_to do |format|
if @member.delete_phone_numbers_and_update(member_params)
format.html { redirect_to @member, notice: 'Member was successfully updated' }
else
format.html { render action: 'edit' }
end
end
end