[英]Rails ActiveModel - Updating nested attributes and adding new ones
I'm a Rails beginner.我是 Rails 初学者。 What I have right now is a Form
that has_many
approvals.我现在拥有的是一个拥有has_many
批准的Form
。
class Form < ApplicationRecord
has_many :form_results
has_many :approvals
accepts_nested_attributes_for :approvals
end
class Approval < ApplicationRecord
belongs_to :form
belongs_to :user
end
When editing :approvals
I need to run some logic.编辑:approvals
时,我需要运行一些逻辑。 Approvals are sequential so they have an order_index
as well as an active
key (similar to a soft delete).批准是顺序的,因此它们有一个order_index
和一个active
键(类似于软删除)。 When a FormResult
gets created, multiple FormResultApprovals
get created based on the data in Approvals
for that form.创建FormResult
时,会根据该表单的Approvals
中的数据创建多个FormResultApprovals
。 What I need to do when updating the Form, I need to see if an Approval has changed for an already existing order_index
.更新表单时我需要做什么,我需要查看 Approval 是否已更改已经存在的order_index
。 If it has I need to mark the existing Approval as active: false
and create a new Approval
for that order_index
.如果有,我需要将现有的 Approval 标记为active: false
并为该order_index
创建一个新的Approval
。
I'm wondering what the "Rails way" of doing this is?我想知道这样做的“Rails 方式”是什么? I have a big chunk of logic that checks all of this and works, but as I discover more and more Rails helpers, I can't help but think there's a better way to do this.我有一大块逻辑可以检查所有这些并且可以正常工作,但是随着我发现越来越多的 Rails 助手,我不禁想到有更好的方法来做到这一点。
The code I have now looks like我现在的代码看起来像
# Grab all current approvals for form that is being edited
# Diff the current against the new ones in the attributes
# If any have of the current approvals have the same id as the "new" ones in the attributes but have a different user associated to them, set active to false on the current approval with that id, and insert a new approval associated to the new user.
I'm using SimpleForm.我正在使用 SimpleForm。
So this is what I came up with.所以这就是我想出的。
class Approval < ApplicationRecord
default_scope { where(active: true) }
belongs_to :form_module
belongs_to :user, optional: true
belongs_to :group, optional: true
before_update :handle_change_in_approver
def create_copy_model
new_approval = Approval.new(order_index: order_index, user_id: user_id, group_id: group_id, form_module_id: form_module_id)
new_approval.save
self.active = false
self.user_id = user_id_was
self.group_id = group_id_was
save
end
def handle_change_in_approver
# User ID changed
if user_id_was != user_id
create_copy_model
elsif group_id_was != group_id
create_copy_model
end
form.form_results.each(&:create_approvals_for_approval_change)
end
end
Basically, whenever a record is updated I run a callback before the update that checks to see if the group_id or user_id has changed.基本上,每当更新记录时,我都会在更新之前运行一个回调,以检查 group_id 或 user_id 是否已更改。 If it has then I create a new Approval
based on the update params, and the return the current Approval
back to it's original state, marking it as active: false
.如果有,那么我根据更新参数创建一个新的Approval
,并将当前Approval
返回到它的原始 state,将其标记为active: false
。 I'm pretty stoked with how this turned out.我对结果如何感到非常兴奋。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.