Use value in override error message in Rails 4 for

2019-08-30 03:18发布

问题:

I am on Rails 4.2 I have written a custom Validator which will check if a value being entered exists in another table. I have been reviewing some other posts and it seems there is either a context specific or rails version preferred way to reuse the value being validated. In the rails docs i see examples such as:

validates :subdomain, exclusion: { in: %w(www us ca jp),
    message: "%{value} is reserved." }

however, if I try to use %{value} in my custom message override it does not interpolate, but just prints "%{value}". I have seen various ways of calling "value". I also could not get %{value} to work in my Validator definition, but could get #{value} to work (New to ruby, if#{value} getting it from validate_each?).

I have also been struggling with various formats of the validation statement and putting in the custom message. Some things which look repeatable from the docs are not. If the way I am declaring my custom message is causing the error, please let me know how to correct?

class ExistingGroupValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless Group.where(:code => value).any?
     record.errors[attribute] << (options[:message] || "#{value} is not a valid
group code")
    end
  end
end

class Example < ActiveRecord::Base
  validates :group_code, presence: true
  validates :group_code, :existing_group => {:message => "The code you have enterd ( **what goes here?** ) is not a valid code, please check with your teacher or group
leader for the correct code." }

end

回答1:

Rails is using Internationalization style string interpolation to add the value to the message. You can use the I18n.interpolate method to accomplish this. Something like this should do the trick:

class ExistingGroupValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless Group.where(:code => value).any?
     record.errors[attribute] << (I18n.interpolate(options[:message], {value: value}) || "is not a valid group code")
    end
  end
end

class Example < ActiveRecord::Base
  validates :group_code, presence: true
  validates :group_code, :existing_group => {:message => "The code you have entered, "%{value}", is not a valid code, please check with your teacher or group   leader for the correct code." }
end


回答2:

Rails automatically puts the value at the beginning of the phrase, so you can just do this:

class ExistingGroupValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless Group.where(code: value).any?
     record.errors[attribute] << (options[:message] || 'is not a valid group code')
    end
  end
end

class Example < ActiveRecord::Base
  validates :group_code, presence: true
  validates :group_code, existing_group: {message: 'is not a valid code, please check with your teacher or group leader for the correct code.' }
end

Separately, note that it is always "#{1+1}" to interpolate not %.