ActiveRecord:如何将属性值插入自定义validation错误消息?
我有一个validates_presence_of :price
validation,当validation失败时返回"Book version price can't be blank"
错误。
class BookVersion < ActiveRecord::Base attr_accessible :name, :book_id, :instock, :isbn, :price, :famis_price, :famis_number, :weight_in_pounds, :width, :height, :thickness validates_presence_of :price, message: "can't be blank"
但是,我想将BookVersion的name
值添加到validation消息中,如下所示:
如果book_version.name
返回“LB”:
Book version LB price can't be blank
所以我想做的事情如下:
validates_presence_of :price, message: "#{self.name} can't be blank"
但那就是返回Book version price BookVersion can't be blank
,这不是我想要的
你得到BookVersion的原因是因为此时validation的范围是Class,而不是你要validation的对象。 这就是在ActiveModelvalidation中设置消息的工作原理。 如果你真的想让validation做你想做的事,你可以写下这样的东西:
validate :presence_of_price private def presence_of_price errors.add(:price, "for #{self.name} can't be blank") if price.blank? end
一种选择是在模型中进行自己的插值:
after_validation do |record| record.errors.messages.each do |k, v| v.each do |message| message.gsub!(/@{(? [^}]*))}/, __send__(col)) end end end
因此,除了Ruby插值( #{...}
)和ActiveModelvalidation插值( %{...}
)之外,您现在还有第三种插值语法 – @{...}
的选择是任意的,但是, IMO,非常适合这种模式。
您可以将它放在ActiveRecord :: Base中,这样就不需要在每个模型中重复它。 当然,这是一种性能成本,所以最好只在需要的地方包含它。
您可能希望查看full_messages
方法。
所以你保留你的: validates_presence_of :price, message: "can't be blank"
如果您想显示错误,可以使用Book version #{book_version.name} #{book_version.errors.full_messages.to_sentence}
您可能希望使用符号作为消息( validates_presence_of :price, message: :cant_be_blank
),因此您可以在语言环境文件中将其翻译( activerecord.errors.messages.cant_be_blank
)