【问题标题】:Rails Active Record: 'attribute_before_last_save' vs 'attribute_was'Rails 活动记录:“attribute_before_last_save”与“attribute_was”
【发布时间】:2018-02-04 17:05:35
【问题描述】:

所以我正在调试一个问题,我是facing,我很难理解为什么attribute_before_last_save 的工作方式与attribute_was 不同,因为在docs 中,我所能得到的只是attribute_before_last_save 的行为类似于attribute_was但在我的情况下,我得到nil 一个和另一个正确的值。

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    attibute_before_last_save只有在你将数据保存到db成功后才能工作。

    如果你在保存前有回调,你应该使用attibute_was

    【讨论】:

      【解决方案2】:

      在 Rails 5.1.4 中查看 attribute_was 的源代码时,您会发现这一行

      emit_warning_if_needed("attribute_was", "attribute_before_last_save")
      

      基于source code,它会引发以下弃用错误

      attribute_was 在 after 回调中的行为将 在下一版本的 Rails 中进行更改。新的返回值将反映 在save 返回后调用方法的行为(例如,与什么相反 它现在返回)。要保持当前行为,请使用attribute_before_last_save 而是。

      【讨论】:

      • I looked it up ,它只会引发弃用警告
      • 我对@9​​87654328@ 中可能出现的问题感兴趣,这给了我nil,而attribute_was 给了我正确的属性值。
      • @AbhinavSrivastava 这不是新纪录吗?你能用你的代码更新你的问题吗?
      【解决方案3】:

      attribute_before_last_save(attr_name):返回上次保存前的属性原始值。 行为类似于attribute_was。这个方法在之后很有用 回调在保存之前获取属性的原始值 刚刚发生的事情

      只是回调后受它们影响

      假设用户模型具有name 属性:

      class User < ApplicationRecord
        after_update :find_name_before_last_save
      
        def find_name_before_last_save
          puts "+++++++++++++++"
          puts name_before_last_save
        end
      end
      

      【讨论】:

      • 你能详细说明after callback部分吗?
      • 是的,我可以。仅供参考,attribute_was 已被弃用,将在 Rails 5.1.4 中被 attribute_before_last_save 取代。我已经更新了答案,你可以检查一下
      【解决方案4】:

      我的代码摘录在哪里(注释显示了它在测试期间输出的内容)以及我决定使用的内容

      class User < ApplicationRecord
      
        devise :database_authenticatable, :registerable, :recoverable,
               :rememberable, :trackable, :validatable, :confirmable,
               :async, :authentication_keys => [:email]
      
        after_update :save_old_email_in_history, if: :saved_change_to_email? # XXX: check the rails documentation for saved_change_to_ATTRIBUTE?
      
        def save_old_email_in_history
          # https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Dirty.html
          #
          # puts(
          #   {
          #     previous_changes: previous_changes,
          #     email_was: email_was,
          #     email: email,
          #     saved_change_to_email: saved_change_to_email,
          #     email_before_last_save: email_before_last_save,
          #   }.to_s
          # )
      
          # In test outputs
      
          # {
          #   :previous_changes=>{
          #     "email"=>["idella@koelpin-rodriguez.com", "wanita_jakubowski@gottlieb.com"],
          #     "confirmed_at"=>[Mon, 01 Nov 2021 13:29:47 EDT -04:00, Mon, 01 Nov 2021 13:30:02 EDT -04:00],
          #     "unconfirmed_email"=>["wanita_jakubowski@gottlieb.com", nil],
          #     "updated_at"=>[Mon, 01 Nov 2021 13:29:57 EDT -04:00, Mon, 01 Nov 2021 13:30:02 EDT -04:00]
          #   },
          #   :email_was=>"wanita_jakubowski@gottlieb.com",
          #   :email=>"wanita_jakubowski@gottlieb.com",
          #   :saved_change_to_email=>["idella@koelpin-rodriguez.com", "wanita_jakubowski@gottlieb.com"],
          #   :email_before_last_save=>"idella@koelpin-rodriguez.com"
          # }
      
          UserEmailHistoryItem.create!(user: self, email: email_before_last_save)
        end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-02-01
        • 2011-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多