我有validates_presence_of :price
验证,验证失败时返回"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
值添加到验证消息中,如下所示:
如果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
,这不是我想要的
答案 0 :(得分:3)
您获得BookVersion的原因是因为此时验证的范围是Class,而不是您要验证的对象。这就是在ActiveModel验证中设置消息的工作原理。如果你真的希望验证能够做你想做的事情,你可以编写类似的东西:
validate :presence_of_price
private
def presence_of_price
errors.add(:price, "for #{self.name} can't be blank") if price.blank?
end
答案 1 :(得分:0)
一种选择是在模型中进行自己的插值:
after_validation do |record|
record.errors.messages.each do |k, v|
v.each do |message|
message.gsub!(/@{(?<col>[^}]*))}/, __send__(col))
end
end
end
因此,除了Ruby插值(#{...}
)和ActiveModel验证插值(%{...}
)之外,您现在还有第三种插值语法 - @{...}
的选择是任意的,但是, IMO,非常适合这种模式。
您可以将它放在ActiveRecord :: Base中,这样您就不需要在每个模型中重复它。当然,这会带来性能成本,所以最好只在需要时加入它。
答案 2 :(得分:0)
您可能希望查看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
)中翻译它