0

手短m.delay_save!に:モデルインスタンスを遅延保存用にマークし(例)、マークされたすべてのモデルを単一の呼び出し(例)で保存する標準のRails機能はありますDelaysManager.commit!か?

冗長に:

ユースケースを考えてみましょう: モデル X のインスタンスを 2 つの異なる方法で更新する必要があります。

def f1
  x = get_instance_of_x
  x.a = 'A'
  x.save!
end

def f2
  x = get_instance_of_x
  x.b = 'B'
  x.save!
end
...
def g
  f1
  f2
end

ここでの問題は、g が X のインスタンスを 2 回保存することです。そして一度やってみたい。の呼び出しsave!をメソッド g に移動することもできますが、より複雑なケースでは、g はどのオブジェクトを保存する必要があるかを認識していない可能性があります。だから私はこれを代わりにこのように見せたい:

def f1
  x = get_instance_of_x
  x.a = 'A'
  x.delay :save!
end

def f2
  x = get_instance_of_x
  x.b = 'B'
  x.delay :save!
end
...
def g
  f1
  f2
  DelaysManager.commit
end

class ActiveRecord::Base
  def delay(*args)
    DelaysManager.delay(self, *args)
  end
end

class DelaysManager
  @@delays = []
  def self.delay(*args)
    @@delays << args
  end

  def self.commit
    @@delays.each { |object, *args| object.public_send(*args) }
    @@delays.clear
  end
end 
4

1 に答える 1

0

変更されたオブジェクトを配列に収集することで、これを回避できます。次に、それらに対してすべて保存を使用するだけです。もちろん、既に変更されたオブジェクトのインスタンスを取得するときは、それが配列に存在するかどうかを確認する必要があります。

def f1
  x = get_instance_of_x(params)
  x.a = 'A'
end

def f2
  x = get_instance_of_x(params)
  x.b = 'B'
end
...
def g
  @array_of_x = []
  f1
  f2
  commit
end

def get_instance_of_x(params)
  x = @array_of_x.select{|a| a.id == params[:id]} || X.find(params)
  @array_of_x << x unless @array_of_x.include(x)
  x
end

def commit
  @array_of_x.each(&:save)
end

もちろん、ニーズに合わせてx = @array_of_x.select{|a| a.id == params[:id]} || X.find(params)行をカスタマイズする必要があります。

于 2012-05-24T15:00:35.830 に答える