0

很快:是否有标准的 Rails 功能来标记模型实例以进行延迟保存(例如m.delay_save!),然后通过单个调用(例如DelaysManager.commit!)保存所有标记的模型?

详细地说

考虑用例:我需要用两种不同的方法更新模型 X 的实例:

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 的实例两次。我想做一次。我可以将调用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 回答