当其他属性发生变化时如何更新一个属性

MCM*_*tan 2 ruby ruby-on-rails ruby-on-rails-5

我是 Rails 新手,可以正确解决这个问题。

当“completed”变为 true 时尝试更新“completed_at”。

我读过这个: https: //api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-changed-3F

并决定在每次更新或保存时添加回调。然后检查“completed”属性是否已更改,如果没有更改,如果为 true,则将“completed_at”更新为当前日期。

方法“check_is_completed”确实被调用,但我无法访问正确的道具并检测是否更改并获取新值

class Task < ApplicationRecord
  belongs_to :user
  validates :name, presence: true

  after_save :check_is_completed
  after_update :check_is_completed

  private 

  # This gets called
  def check_is_completed
    # try 1
    # This does not work called
    if @completed.changed?
      if @completed == true
      self.completed_at = Date.new()
      end
    end
    #try 2
    if self.completed_changed?
      if self.completed == true
      self.completed_at = Date.new()
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

Mar*_*ark 5

你已经差不多了。您的问题是您在保存之后而不是之前执行检查。保存记录后,更新已经发生,因此系统认为没有任何更改。

改变

  after_save :check_is_completed
  after_update :check_is_completed
Run Code Online (Sandbox Code Playgroud)

  before_save :check_is_completed
Run Code Online (Sandbox Code Playgroud)

您也不需要使用任何实例变量。由于您已经在班级中,因此您需要做的就是:

def check_is_completed
  return unless completed_changed?
  self.completed_at = Date.new() if completed?
end
Run Code Online (Sandbox Code Playgroud)

这将在每次保存之前执行检查,除非完成的属性已更改,否则不执行任何操作,然后仅在完成为 true 时更新completed_at 字段