before_save除了新记录外,如果字段值发生变化

时间:2017-07-08 20:51:14

标签: ruby ruby-on-rails-4

如果字段发生变化,我需要在rails4 app中执行一个钩子,并且只有当它不是记录记录时才需要。

我知道我能做到......

  before_save :reset_confirmation, if: :email_changed?
  def reset_confirmation
    self.confirmed_at = nil
    self.confirmation_sent_at = nil
  end

我很确定这有效......

  before_save :reset_confirmation, unless: new_record?
  def reset_confirmation
    self.confirmed_at = nil
    self.confirmation_sent_at = nil
  end

但是我如何将两者结合起来,或者是否有更简单的方法来实现我想要的东西并且我会过度思考。如果字段(电子邮件)有帮助,它将始终包含一个值?

3 个答案:

答案 0 :(得分:1)

您可以在回调中使用多个条件,例如:

before_save :reset_confirmation, if: :email_changed?, unless: :new_record?

def reset_confirmation
  self.confirmed_at = nil
  self.confirmation_sent_at = nil
end

或者,您可以添加另一种方法来检查两种情况,例如:

before_save :reset_confirmation, if: :email_changed_and_its_not_new_record?

def reset_confirmation
  self.confirmed_at = nil
  self.confirmation_sent_at = nil
end

def email_changed_and_its_not_new_record?
  email_changed? && !new_record?
end

您可以找到有关条件回调的更多信息here

答案 1 :(得分:0)

我最终还是接受了这个......

  before_update :reset_confirmation, if: :email_changed?
  def reset_confirmation
    self.confirmed_at = nil
    self.confirmation_sent_at = nil
  end

逻辑是before_update只在现有记录上运行,它处理新的记录问题,现在它不会进入方法,除非满足条件以重置字段。

答案 2 :(得分:0)

我想知道当回调被显式setter方法替换时,类的可读性和可维护性是否会提高:

def email=(new_email)
  unless new_email == email 
    self.confirmed_at = nil
    self.confirmation_sent_at = nil
    write_attribute(:email, new_email)
  end
end