如何为 'validate' 自动设置错误消息?

How can I set the error message automatically for 'validate'?

通过使用 validates 对特定属性进行验证,可以使用 :message 选项指定验证失败时要使用的 i18n 消息的键:

模型中:

class Foo < ApplicationRecord
  validates :some_attribute, ...., message: :bar
end

语言环境:

en:
  activerecord:
    errors:
      models:
        foo:
          attributes:
            some_attribute:
              bar: "Blah blah"

如何使用 validate 方法而不是 validates 的验证(不特定于单个属性)做相应的事情?

使用 validate

class Foo < ApplicationRecord
  validate do
    if ERROR_CONDITION
      errors.add(:some_attribute, :bar)
    end
  end
end

或将 validate 与方法

结合使用
class Foo < ApplicationRecord
  validate :some_custom_validation_name

  private

  def some_custom_validation_name
    if ERROR_CONDITION
      errors.add(:some_attribute, :bar)
    end
  end
end

errors.add 可以像下面这样使用:

  • errors.add(ATTRIBUTE_NAME, 符号)

    • SYMBOL 对应于 message 名称。见 message column here in this table
    • 即这可以是 :blank:taken:invalid:bar(您自定义的 message 名称)

      errors.add(:some_attribute, :taken)
      # => ["has already been taken"]
      
      errors.add(:some_attribute, :invalid)
      # => ["has already been taken", "is invalid"]
      
      errors.add(:some_attribute, :bar)
      # => ["has already been taken", "is invalid", "Blah blah"]
      
  • errors.add(ATTRIBUTE_NAME, SYMBOL, HASH)

    • 同上,只是您还可以将参数传递给消息。请参阅您需要使用的 interpolation column here in the same table

      errors.add(:some_attribute, :too_short, count: 3)
      # => ["is too short (minimum is 3 characters)"]
      errors.add(:some_attribute, :confirmation, attribute: self.class.human_attribute_name(:first_name))
      # => ["is too short (minimum is 3 characters)", "doesn't match First name"]
      
  • errors.add(ATTRIBUTE_NAME, 字符串)

    • 或传递自定义消息字符串

      errors.add(:some_attribute, 'is a bad value')
      # => ["is a bad value"]
      

此外,假设您打算像示例中那样将 :bar 作为参数传递给您的验证,那么您可以使用自定义验证器:

# app/validators/lorem_ipsum_validator.rb
class LoremIpsumValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    if ERROR_CONDITION
      record.errors.add(attribute, options[:message])
    end
  end
end

# app/models/foo.rb
class Foo < ApplicationRecord
  validates :some_attribute, lorem_impsum: { message: :bar }
  # or multiple attributes:
  validates [:first_name, :last_name], lorem_impsum: { message: :bar }

  # you can also combine the custom validator with any other regular Rails validator like the following
  # validates :some_attribute,
  #   lorem_impsum: { message: :bar },
  #   presence: true,
  #   length: { minimum: 6 }
end

看来不可能那样做。我必须在验证方法中手动添加错误消息。