Rails +单表继承:如何自定义验证错误消息?

时间:2014-07-08 15:16:06

标签: ruby-on-rails

我有一个父类:

class Address < ActiveRecord::Base
  ...
  validates_presence_of :first_name
  validates_presence_of :last_name
  validates_presence_of :street_address
  validates_presence_of :street_address2
  validates_presence_of :zip_code
  validates_presence_of :city
  validates_presence_of :state_id
  validates_presence_of :phone_number

end

还有两个子类:

class ShippingAddress < Address
end


class BillingAddress < Address
end

但是,当我在表单上创建无效记录时(我正在同时创建两个记录),ShippingAddress和BillingAddress的验证错误是相同的,这是我不想要的:

First name can't be blank
First name can't be blank
Last name can't be blank
Last name can't be blank
Street address can't be blank
Street address can't be blank
Street address2 can't be blank
Street address2 can't be blank
Zip code can't be blank
Zip code can't be blank
City can't be blank
City can't be blank
Phone number can't be blank
Phone number can't be blank

如何将验证错误添加到类名"Shipping address first name can't be blank"

之前

== UPDATE ==

当我尝试时,Yoshi的回答不起作用:

class Address < ActiveRecord::Base  
  validates_presence_of :first_name, message: I18n.t("activerecord.errors.models.#{self.model_name.to_s.underscore}.attributes.first_name")




Nets-Mac-Pro:ilook emai$ be rails c
Loading development environment (Rails 4.1.1)
irb(main):001:0> s = ShippingAddress.new
=> #<ShippingAddress id: nil, first_name: nil, last_name: nil, street_address: nil, street_address2: nil, zip_code: nil, phone_number: nil, created_at: nil, updated_at: nil, state_id: nil, city: nil, type: "ShippingAddress", order_id: nil>
irb(main):002:0> s.valid?
=> false
irb(main):003:0> s.errors.full_messages
=> ["First name translation missing: en.activerecord.errors.models.address.attributes.first_name", "Last name can't be blank", "Street address can't be blank", "Street address2 can't be blank", "Zip code can't be blank", "City can't be blank", "State can't be blank", "Phone number can't be blank"]

它表示型号名称是Address而不是ShippingAddress。我猜这是急切的。

2 个答案:

答案 0 :(得分:0)

要修复此问题,我只是将其添加到我的en.yml文件中:

en:
  activerecord:
    attributes:
      shipping_address:
        first_name: "Shipping address first name"
        last_name: "Shipping address last name"
        street_address: "Shipping address street address"
        street_address2: "Shipping address apt/suite"
        zip_code: "Shipping address zip code"
        city: "Shipping address city"
        state_id: "Shipping address state"
        phone_number: "Shipping address phone number"
      billing_address:
        first_name: "Billing address first name"
        last_name: "Billing address last name"
        street_address: "Billing address street address"
        street_address2: "Billing address apt/suite"
        zip_code: "Billing address zip code"
        city: "Billing address city"
        state_id: "Billing address state"
        phone_number: "Billing address phone number"

答案 1 :(得分:0)

Rails使用human_attribute_name将属性名称转换为人类可读的形式。您可以尝试在ShippingAddressBillingAddress中重写此类方法,以避免必须在语言环境文件中指定每个验证消息。

class ShippingAddress < Address
  def self.human_attribute_name(*args, &block)
    "Shipping address #{ super }"
  end
end

class BillingAddress < Address
  def self.human_attribute_name(*args, &block)
    "Billing address #{ super }"
  end
end