2016-09-09 101 views
0

我想顯示來自Child模型的驗證消息,它給我的基本Child是無效的。我嘗試了所有解決方案,但沒有成功。 這裏,總之,是機型:Rails validates_associated和錯誤消息

Class Parent 
    ... 
    has_many :children, dependent: :destroy, inverse_of: :parent 
    accepts_nested_attributes_for :children, allow_destroy: true 
end 

Class Child 
    belongs_to :parent 
    validate :something 
    def something 
    check = # Here I check something 
    if check < 5 
     errors[:base] << "validation on children failed" 
    end 
    end 
end 

如果我添加validates_associated :children到父模型,然後我居然得到兩個Children is invalid消息,這是有點兒奇怪。

反正,我可以將此塊添加到父模型,並得到任何驗證消息我想添加到父:基礎錯誤列表:

validate do |parent| 
    parent.children.each do |child| 
    check = # Here I check something 
    if check < 5 
     errors[:base] << "validation on children failed" 
    end 
    end 
end 

不過,我還是會從驗證錯誤消息在這個之上的孩子模型,所以現在我們會有3個錯誤消息:「孩子是無效的孩子是失敗的孩子無效驗證」...醜陋。

由於我將模塊添加到父模型中,我可以從子模型中刪除驗證,從父類中刪除validates_associated :children,然後保存實例將不會通過驗證,但屬於子模型的數據將沒有驗證並保存/更新。

希望對此有清楚的解釋。如果您可以提供解決方案,那將非常棒!

更新1:關於accepts_nested_attributes_for

這是非常糟糕記錄。正如我所解釋的,我在沒有請求的情況下對我的nsted模型進行驗證。我相信原因是accepts_nested_attributes_for實際上運行嵌套模型的驗證。 這意味着無論驗證類型如何,我從嵌套模型獲取的所有驗證消息都會給我一條消息。我可能會設法以某種方式調整該消息的輸出,但它仍然是一個單一的消息,並不針對嵌套模型遇到的問題。

話雖如此,accepts_nested_attributes_for確實允許reject_if論點。這並不能真正幫助我,因爲我需要在嵌套模型上運行多個條目的唯一性驗證(一個父級的許多孩子都需要具有唯一的名稱)。

摘要:

我相信我需要運行在子模型的驗證,但找到一個方法來報到的家長模式,通過accepts_nested_attributes_for,與具體消息。這實質上是我正在尋找的! 我想我需要寫一個自定義驗證器。有任何想法嗎?

+0

你試過這個'validates_associated:children,:message => lambda {| class_obj,obj | obj [:value] .errors.full_messages.join(「,」)}' –

+0

在你的孩子模型中...爲什麼你給孩子添加一個錯誤? 'errors.add(:children'''''''當然你只是將錯誤添加到無效的屬性中(或基本的)? –

+0

@VrushaliPawar - 這不起作用,而且,如果它確實起作用,它會是隻限於一條消息,而不是特定於驗證失敗的原因。查看我上面有關「accepting_nested_attributes_for」的更新內容 – Ben

回答

0

提出的解決方案

這樣簡單的事情不應該如此惱人的修復。我仍然沒有找到任何優雅的解決方案,但我沒有更多的時間浪費在這方面。 公平對待其他人,我會發布我的(醜陋的)解決方案。請注意,此解決方案仍需要工作。

我最終創建了一個方法來從兩個模型中收集錯誤,而不是讓Rails執行它。

def collect_errors 
    errors = [] 
    if self.errors.any? 
    parent_errors = self.errors.full_messages 
    parent_errors.delete("YOURCHILDMODELNAME is invalid") 
    errors << parent_errors.join(", ") 
    end 
    self.children.each do |child| 
    if child.errors.any? 
     errors << child.errors.messages.values.join(", ") 
    end 
    end 
    return errors.join(", ") 
end 

我那麼做的每個模型中的所有驗證,並在視圖中我簡單地顯示收集的錯誤,而不是父模型錯誤:

flash[:warning] = "Failed to create Parent: #{@parent.collect_errors}" 
0

添加我的解決方案,我希望這是有幫助的人瀏覽這個問題:

class Parent < AR 
    has_many :children, inverse_of: :parent 
    validates_associated :children, message: proc { |_p, meta| children_message(meta) } 

    def self.children_message(meta) 
    meta[:value][0].errors.full_messages[0] 
    end 
    private_class_method :children_message 
end 

class Child < AR 
    belongs_to :parent, inverse_of: :children 
    validates :name, presence: true 
end