首页 > 解决方案 > Rails ActiveModel - 更新嵌套属性并添加新属性

问题描述

我是 Rails 初学者。我现在拥有的Formhas_many批准。


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

编辑时:approvals我需要运行一些逻辑。批准是连续的,因此它们有一个order_index和一个active键(类似于软删除)。创建一个时,会根据该表单中的数据FormResult创建多个。更新表单时我需要做什么,我需要查看 Approval 是否已更改为已经存在的. 如果有,我需要将现有的 Approval 标记为并为此创建一个新的。FormResultApprovalsApprovalsorder_indexactive: falseApprovalorder_index

我想知道这样做的“Rails 方式”是什么?我有一大块逻辑可以检查所有这些并且可以正常工作,但是随着我发现越来越多的 Rails 助手,我不禁想到有更好的方法来做到这一点。

我现在的代码看起来像

# 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.

我正在使用 SimpleForm。

标签: ruby-on-railsactiverecordrails-activerecord

解决方案


所以这就是我想出的。

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

基本上,每当更新记录时,我都会在更新之前运行一个回调,以检查 group_id 或 user_id 是否已更改。如果有,那么我Approval根据更新参数创建一个新参数,并将当前Approval返回到它的原始状态,将其标记为active: false. 我对结果如何感到非常兴奋。


推荐阅读