読者です 読者をやめる 読者になる 読者になる

validatesでうまくlambdaを扱えなかったメモ

rails
Ruby version              1.9.3 (i386-mingw32)
Rails version             3.2.12
Database adapter          oracle_enhanced

モデルで

validates :user, 
  presence: {if: lambda{via == "abc.com"}}, 
  customer_master: {address_presence: lambda{via == "abc.com"}}

と書いて、このcustomer_masterバリデータを

class CustomerMasterValidater << ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    master = Customer.find(value)
    if master.blank?
      errors[attribute] << I18n.t('errors.validation.user_not_found')
    elsif options[:address_presence].call
      errors[attribute] << I18n.t('errors.validation.user_addr_not_found')
    end
  end
end

と書くとうまく動かない。options[:address_presence].callのところがうまくない。

:if/unlessオプションはどこかで適当にProcをcallしているのだと思われる。なのでpresence: {if: lambda{via == "abc.com"}}という書きっぷりは問題ない。

でも自前バリデータの自前オプションにlambdaを渡したら自分でcallしなきゃならない様子。 従ってvalidator側はcall(record)としてmodel側ではlambda{|r| r.via == "abc.com"}とlambdaに引数でrecordを渡してやらないと、上記の書き方では「viaなんてローカル変数しりませんがな」と言われる。