简体   繁体   English

Rails ActiveModel - 更新嵌套属性并添加新属性

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM