【问题标题】:Update on record would update all other records in model, global ordering in rails 3.1更新记录将更新模型中的所有其他记录,rails 3.1 中的全局排序
【发布时间】:2011-10-17 10:07:48
【问题描述】:

当我更新单个记录的属性时,我想更新 rails (3.1) 模型中的所有记录。

像 self.update_attribute(:global_order => 1) 然后在保存之前或之后想要更新所有其他记录以更新他们的 global_order (1, 2, 3, 4)。

现在在使用 after_save 回调时,我陷入了递归循环,跳过回调是要走的路吗?如果 global_order 中有任何奇怪的地方,我希望应用程序抛出异常。

或者是否有任何 3.1 gem 可以解决我的问题。

after_save :set_global_order

def set_global_order
    @products = self.class.all(:order => :global_order)
    @products.sort! {|a,b| a.global_order <=> b.global_order}
    @products.reverse!
    @products.each_with_index do |p, index|
        p.update_attributes!({:global_order => index + 1})
    end
end

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord ruby-on-rails-3.1


    【解决方案1】:

    不确定是否有 gem,但您绝对可以考虑以下因素来重构它:

    • 当使用本地变量时,无需使用实例变量污染对象
    • 前三行排序相同的集合,为什么不这样做一次?

    ...

    def set_global_order
      products = self.class.order('global_order DESC')
    
      products.each_with_index do |p, index|
        p.update_column(:global_order, index + 1)
      end
    end
    

    【讨论】:

    • 这不会解决我在 after_save 回调中运行递归的问题。有什么方法可以跳过回调或者你将如何解决问题。
    • 啊,好点,我更新了我的答案,改用update_column。我相信这是唯一跳过回调的方法。但是,查看此方法的源代码时,它有点令人困惑,并且似乎正在使用相同的值更新每条记录。您可能需要对它进行一些试验。还有一个由 update_column 调用的write_attribute 方法。如果事实证明 update_column 正在更新所有记录,我也会尝试这样做。
    • update_columndoes 正如你所说的更新单个记录。感谢您的提示。仍然无法订购产品列表,开始查看acts_as_list,但似乎很难在没有范围的同一型号上使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-26
    • 2014-09-01
    • 1970-01-01
    • 2013-03-08
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多