2016-08-18 19 views
0

我在我的應用程序相當長的一段belongs_to的關聯,他們中的一些是可選的(即聯想可能是無),有些是強制性的(協會必須是有效的父記錄。爲belongs_to的關聯設定驗證錯誤消息變得容易

我最初的做法是用我自己的驗證方法來驗證給定的ID(這裏的強制性協會)

belongs_to :category 

validates :category_id, 
    presence: true 

validate given_category_exists 

def given_category_exists 
    if category_id.present? 
    errors.add(:category_id, 'must be present') \ 
     Category.exists?(category_id) 
    end 
end 

然後我發現的Rails會爲我做,如果我會用存在支票上的關聯所以我可以省略我自己的驗證方法:

belongs_to :category 

validates :category, 
    presence: true 

但現在,生成的錯誤消息將簡單地陳述爲:Category can't be blank。這裏的問題是:(1)我可以提供更有用的信息嗎? (2)如何爲屬性插入我自己的翻譯? Category是由驗證方法生成的默認標籤,can't be blank是以下內容的默認錯誤文本:空白。

此問題的另一個問題:表單中的相關輸入字段未標記爲'field_with_errors',因爲此字段使用屬性名稱標識,而不是關聯名稱。

使用做事的標準的方式,我會額外的屬性添加到我的I18n翻譯文件的關聯category的名稱,並增加了對標準信息的替代品:

en: 
    activerecord: 
    models: 
     attributes: 
     my_model: 
      category_id: 'This Category' 
      category: 'This Category' 

    errors: 
     models: 
     my_model: 
      attributes: 
      category: 
       blank: 'must be specified.' 

很多線,其中的事情可能會出錯。我不喜歡這個想法添加表面屬性,這些表面屬性實際上不是屬性,而是關聯的名稱。

有沒有更簡單的方法?

+0

不,您可能使用最簡單的方法來防止後來的麻煩。 – Supernini

回答

0

我的解決方案是重寫error.add方法,它證明是非常簡單和非常有效的。 Rails協會包含所有需要的信息,我只需要在那裏找到它。我甚至可以使用對關聯的class_name的引用來格式化自己的錯誤消息!現在我的錯誤信息是這樣的:

This Category must be one of the existing Categories. 
  1. 添加了新的標準錯誤消息:

    en: 
        messages: 
        blank_assoc: 'must be one of the existing %{assoc}' 
    
  2. 添加下列文件到應用程序/模型/憂慮文件夾

    module ActiveModelErrorsAdd 
        def add(attribute, message = :invalid, options = {}) 
         if attribute != :base # that's the only other attribute I am using 
         all_assocs = @base.class.reflect_on_all_associations(:belongs_to) 
         this_assoc = nil 
         all_assocs.each do |a| 
         if a.name == attribute 
          this_assoc = a 
          break 
         end 
         end 
        end 
        if this_assoc.nil? # just use the standard 
         super 
        elsif message == :blank # replace with my own 
         super(this_assoc.foreign_key, :blank_assoc, 
         options.merge(assoc: this_assoc.klass.model_name.human)) 
        else # use standard message but refer to the foreign_key! 
         super(this_assoc.foreign_key, message, options) 
        end 
        end 
    end 
    
    class ActiveModel::Errors 
        prepend ActiveModelErrorsAdd 
    end 
    
  3. 將此文件包含在需要的模型中,並且您將獲得所有你的良好錯誤消息gs_to關聯。請享用!

注意:此方法也導致了正確的輸入字段被標記爲「field_with_errors」 - 即使它有一個非標準的外鍵!

1

該帖子很舊,但我仍然會寫我的解決方案。導軌5具有您可以使用支付驗證消息,對於那些屬於關聯一個required錯誤鍵:

class MyModel < ApplicationRecord 
    belongs_to :category 
end 

注意,你實際上並不需要在這裏指定驗證規則(validates :category, presence: true)。爲了定製您的信息,只需使用required鍵:

en: 
    activerecord: 
    errors: 
     models: 
     my_model: 
      attributes: 
      category: 
       required: "The category must be specified."