2016-09-09 77 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