Каскад обновления по ассоциации - PullRequest
1 голос
/ 19 февраля 2020

У меня есть класс Yojana и еще один класс Kabuliyat, где Кабулиат принадлежит Йоджане, а у Йоджаны есть один кабулиат.

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

Некоторые из полей / атрибутов экземпляр kabuliat зависит от атрибутов экземпляра yojana .

Например, в частичной форме для нового кабулиата .

- @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}

Как видите, такие атрибуты, как : yojana_name и : mukhya_samitit для экземпляра kabuliyat извлекаются из его родительского атрибута экземпляров yojana.

Проблема:

Я хотел бы знать, есть ли у меня экземпляр из сохраненного Кабулиата, а затем я отредактировал экземпляр Йоджаны, от которого зависят атрибуты Кабулиата, как я смогу также отразить изменения в экземпляре Кабулиата.

Например : Если я изменю имя экземпляра Yojana с «A» на «B», может ли это изменение автоматически отразиться на атрибуте kabuliyat дочернего экземпляра (например, yojana_name).

Что у меня есть попробовал:

Я использовал обратный вызов before_update в классе модели Yojana.rb и вручную изменил все остальные зависимые классы на Yojana. Я хотел знать, есть ли другой эффективный метод.

1 Ответ

2 голосов
/ 19 февраля 2020

Создайте сервис, 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

Конечно, вы можете внести значительные улучшения в код, но это просто, чтобы дать представление о том, как Вы можете подойти к этой проблеме.

...