首页 > 解决方案 > 关联的级联更新

问题描述

我有一个班级Yojana和另一个班级Kabuliyat,其中 Kabuliyat 属于 Yojana,而一个 Yojana 有一个 kabuliyat。

class Yojana < ApplicationRecord
  has_one :kabuliyat, dependent: :destroy
end
class Kabuliyat < ApplicationRecord
  belongs_to :yojana
end

kabuliat 实例的某些字段/属性取决于yojana 实例的属性。

例如新的 kabuliyat的部分形式。

- @yojana = Yojana.find_by_id(params[:yojana_id])

= form_for kabuliyat do |f|
tr
    td = f.label :yojana_name
    td = f.text_field :yojana_name, {value: @yojana.yojana_name,class: "hide-input",:readonly => true}

tr
    td = f.label :mukhya_samiti
    td = f.text_field :mukhya_samiti, {value: @yojana.mukhya_samiti,class: "hide-input",:readonly => true}

如您所见, kabuliyat 实例的:yojana_name:mukhya_samitit等属性是从其父 yojana 实例属性中提取的。

问题:

我想知道,如果我保存了 kabuliyat 的实例,然后我编辑了 Kabuliyat 的属性所依赖的 Yojana 的实例,我将如何能够反映 kabuliyat 的实例上的更改。

例如:如果我将 Yojana 实例的名称从“A”更改为“B”,这种更改是否会自动反映在子实例 kabuliyat 的属性上(例如:yojana_name)。

我试过的:

我在Yojana.rbbefore_update模型类中使用了回调,并手动更改了 Yojana 上所有其他依赖的类。我想知道是否还有其他有效的方法。

标签: ruby-on-railsrubyassociations

解决方案


创建一个服务,UpdateYojana你可以这样做,

class UpdateYojana
  attr_reader :yojana, :kabuliyat

  def initialize(yojana)
    @yojana = yojana
    @kabuliyat = yojana.kabuliyat
  end

  def self.update(yojana_id, params)
    yojana = Yojana.find(yojana_id)
    new(yojana).update(params)
  end

  def update(params)
    return false unless valid?

    ApplicationRecord.transaction do
      if yojana.yojana_name_changed? or yojana.mukhya_samiti_changed?
        kabuliyat.update!(yojana_name: yojana.yojana_name, mukhya_samiti: yojana.mukhya_samiti)  
      end
      yojana.save!
    end
  end

  private

  def valid?(params)
    params.each do |attr, value|
      yojana.public_send("#{attr}=", value)
    end
    yojana.valid?
  end
end

当然,您可以对代码进行很多改进,但这只是为了让您了解如何解决此问题。


推荐阅读