ActiveRecord getter中断验证

Bor*_*tov 5 ruby validation activerecord ruby-on-rails

我需要验证信用卡号码.

model Billing
  validates :card, credit_card_number: true, allow_nil: true
Run Code Online (Sandbox Code Playgroud)

验证宝石代码:

  def validate_each(record, attribute, value)
    record.errors.add(attribute, options[:message] || :invalid) unless credit_card_valid?(value, extract_brands(record, options))
  end
Run Code Online (Sandbox Code Playgroud)

它工作正常.但后来我尝试用这种方式覆盖geter:

   def card
    "****#{self[:card][-4,4]}" if self[:card]
   end
Run Code Online (Sandbox Code Playgroud)

验证失败.当我猴子修补validates_each像那样:

  def validate_each(record, attribute, value)
    value = record[attribute]
    record.errors.add(attribute, options[:message] || :invalid) unless credit_card_valid?(value, extract_brands(record, options))
  end
Run Code Online (Sandbox Code Playgroud)

它恢复运作良好.验证getter而不是持久化值是否是正确的验证行为(validates_each第一个变体是遵循指南).或者什么是解决我的问题的优先方式?更新:Activemodel/Activerecord版本:4.2.3

Bro*_*tse 1

首先,您定义的方法不是模型关注点 - 它是视图关注点,因此应该移至助手或演示者。然而,在模型中使用此类方法是非常常见的做法,因此我不会说这是一个大问题。

您可以通过为您的方法选择其他名称来轻松解决整个问题:

def starred_card
  card && "****#{card[-4,4]}"
end
Run Code Online (Sandbox Code Playgroud)