在ActiveModel::EachValidator中检查attribute_changed?。

huangapple go评论65阅读模式
英文:

Checking if attribute_changed? in ActiveModel::EachValidator

问题

我有一个名为Person的类,它有first_name、middle_name和last_name这三个属性。
我有一个自定义的Each验证器,用于这三个属性,如下所示:

validates :first_name, :middle_name, :last_name, nameValidator: true

在这个验证器中,我想要检查这3个属性中是否有任何一个发生了变化,并在满足一些其他条件的情况下验证名称。为此,我正在尝试使用attribute_changed?,但它不起作用。

我已经查看了ActiveModel::Dirty和Activerecod::Dirty的不同方法,但似乎没有任何方法可以检查每个属性的变化。我漏掉了什么?

module Person
  class nameValidator < ActiveModel::EachValidator

    def validate_each(record, attribute, value)
      return unless can_normalize?(record)
      #规范化代码 
    end

    def can_normalize?(record)
      anything_new = record.new_record? || record.attribute_changed?(attribute)
    end
  end
end
英文:

I have a class Person that has first_name, middle_name, last_name.
I have a customed Each validator for these 3 attributes like so

validates :first_name, :middle_name, :last_name, nameValidator: true

In this validator I want to check if any one of these 3 attributes changed and given a few more conditions I'll validate name. For that I'm trying attribute_changed? but it doesn't work.

I've checked different methods from ActiveModel::Dirty and Activerecod::Dirty but nothing seems to work to check changes in each attribute. What am I missing?

module Person
  class nameValidator < ActiveModel::EachValidator

    def validate_each(record, attribute, value)
      return unless can_normalize?(record)
      #Normalization code 
    end

   def can_normalize?(record)
      anything_new = record.new_record? || attribute_changed?
   end
  end
end

答案1

得分: 2

如果你需要检查某个属性是否发生了变化,你需要在记录上调用 attribute_changed? 方法,并传递这个属性,如下所示:

return unless record.new_record? || record.attribute_changed?(attribute)

或者可以使用元编程的方法,如下所示:

return unless record.new_record? || record.public_send("#{attribute}_changed?")

一些注意事项:

在 Ruby 中,通常我们使用 PascalCase 来命名类,使用 snake_case 来命名哈希键。

验证通常用于数据验证,而不是一些规范化工作。它通常用于添加验证错误。

英文:

If you need to check that some attribute was changed, you need to call attribute_changed? method on the record and pass this attribute like this

return unless record.new_record? || record.attribute_changed?(attribute)

Or may be use metaprogramming method like this

return unless record.new_record? || record.public_send("#{attribute}_changed?")

Some notes:

In Ruby we usually use PascalCase for class names and snake_case for hash keys

Validations are used for data validation, not for some normalization. It is usually used to add validation errors

huangapple
  • 本文由 发表于 2023年1月9日 06:00:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75051580.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定