【问题标题】:How to check modified value in a model's before_save callback?如何检查模型的 before_save 回调中的修改值?
【发布时间】:2011-12-17 18:48:59
【问题描述】:

如何读取控制器在 before_save 回调中设置的值?

例子:

我有一个带有url 字段的模型。在保存之前,我想检查 url 是否已更改。如果是这样,请同时使用新网址和旧网址。

这可能吗?

【问题讨论】:

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


    【解决方案1】:

    试试这样的:

    before_save { |m| if m.url_changed? ... }
    

    另请参阅ActiveModel::Dirty 上的文档

    【讨论】:

    • 感谢您改变主意并取消删除您的答案,这是正确的方法。特别是,url_changed?url_wasurl_change 方法很有趣。
    • 我最终使用 paper_trail 来完成这项工作。
    【解决方案2】:

    更好的方法

    before :todo, if: :first_name_or_last_name_changed?
    

    还有你的 todo 方法

    def first_name_or_last_name_changed?
       first_name_changed? || last_name_changed?
    结束

    【讨论】:

    • 您能否edit 重新格式化为代码块(Ctrl-K 或四个前导空格),这样更具可读性?请务必检查编辑框下方的预览。
    • 我想这可能就是你要找的。​​span>
    【解决方案3】:

    如果它发生了变化,它应该在params 散列中。如果它没有改变,它不应该在那里。因此,您可以将此自定义处理放入控制器中,或者放入执行此操作的模型上的方法中。

    如果您真的想在before_save 中访问它,请查看有关 ActiveRecord 回调的文档,您将了解如何访问之前和之后的值。

    【讨论】:

    • 不,这种事情不属于控制器,模型应该负责管理自己的内部。如果 url 被修改为设置不同属性的副作用,会发生什么?也许before_validation 钩子会查看其他属性并更新url,这与控制器无关。或者,before_save 可能被用于跟踪模型的修订历史,这也与控制器无关。
    • 明白。我只是提供了多种方法,包括使用before_save 的方法。最初的提问者并没有真正进入他们想要根据 url 的值做的事情(例如,重定向到其他地方 - 在控制器中完成的事情),所以我不想假设目的是什么。我只是指出了您可以从哪些地方获得这些信息。
    【解决方案4】:

    我试过这个东西,但没有成功

    #Non-working code
    before_save: record_old_value
    after_save: record_change
    
    def record_old_value
       @old_value = self.field
    end
    
    def record_change
       if @old_value==self.field
          create_record_in_history :old_value => @old_value, :new_value => self.field
       end
    end
    

    它没有成功的原因是因为我们设置了 self.field=new_value 所以在 before_save 中它是不可访问的。但是 rails 有更多的 Active-record 函数,比如 field_changed,可以直接在 before_save 和 after_save 中使用。所以我最终得到了这个解决方案

    #working code
    after_save :run_function
    def run_function
       @old_value = field_was
       if @old_value==self.field
          create_record_in_history :old_value => @old_value, :new_value => self.field
       end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多