运维开发网

ruby-on-rails – 在Rails 4中验证循环关联的正确方法是什么?

运维开发网 https://www.qedev.com 2020-07-25 09:37 出处:网络 作者:运维开发网整理
鉴于: def Node belongs_to :parent, class_name: :Node has_many :children, class_name: :Node, foreign_key: :parent_id end 我正在尝试创建一个验证,以确保节点不能是它自己的父节点,或它的父节点的父节点等. 我懂了: # Custom validator to check if t
鉴于:

def Node
  belongs_to :parent, class_name: :Node
  has_many :children, class_name: :Node, foreign_key: :parent_id
end

我正在尝试创建一个验证,以确保节点不能是它自己的父节点,或它的父节点的父节点等.

我懂了:

# Custom validator to check if the Parent Node is related to the current node. Avoids that ugly self-association loop.
#
class NodeParentValidator < ActiveModel::Validator
  def validate(node)
    @node = node

    unless validate_recursive(node)
      node.errors[:parent_id] << "Node can't be it's own parent"
    end

  end

  def validate_recursive(node)
    # If the validating node doesn't have a parent, we return true because we're either facing a node that doesn't have any parent
    # or we got to the point that we need to stop the recursive loop.
    return true if node.parent.nil?
    # If the validating node is the same as the current "parent", we found the self-association loop. This is bad.
    return false if @node.id == node.parent_id
    # While we don't get to the end of the association, keep jumping.
    return false unless validate_recursive(node.parent)
    return true
  end

end

它完全有效!实际上这就是问题所在.它有效吗?当Rails调用assign_attributes方法时,我得到一个422,但它没有我的验证!相反,我得到一个丑陋的HTML验证错误,如下所示:

ActiveRecord::RecordNotSaved (Failed to replace children because one or more of the new records could not be saved.)

因此,如果Rails无法保存它的相关记录,Rails会返回它自己的错误(上面代码块中的错误),但是如果我的Record与自身相关联,那么我会遇到很大的问题.即使我阻止节点验证它的相关子节点/父节点,我仍然会收到错误.

只要我试图保存ITSELF的记录有错误,那么Rails用上面的错误替换我的422.这简直太糟糕了.我想要一个JSON响应错误,所以我的客户端知道到底出了什么问题.

我发现很难相信没有其他人遇到过这个问题,我错过了什么吗?

你有没有在Node模型中调用验证器?如果是这样,上面的代码应该工作.

我试过这个,

class Node < ActiveRecord::Base
   has_many :children, class_name: :Node, foreign_key: :parent_id
   belongs_to :parent, class_name: :Node, foreign_key: :parent_id

   validates_with NodeParentValidator
end

验证器代码是相同的.这是在控制台中测试的结果.

ruby-on-rails – 在Rails 4中验证循环关联的正确方法是什么?

0

精彩评论

暂无评论...
验证码 换一张
取 消