【问题标题】:accepts_nested_attributes_for validation接受嵌套属性用于验证
【发布时间】:2010-10-25 04:08:33
【问题描述】:

我正在使用 Rails 2.3.8 并接受_nested_attributes_for。

我有一个简单的类别对象,它使用 awesome_nested_set 来允许嵌套类别。

对于每个类别,我想要一个称为代码的唯一字段。对于每个级别的类别,这将是唯一的。这意味着父类别都有唯一的代码,子类别在它们自己的父类别中是唯一的。

EG:

code name
1    cat1
   1 sub cat 1
2    cat2
   1 sub cat 1
   2 sub cat 2
3    cat3
   1 sub1

这在没有验证过程的情况下有效,但是当我尝试使用类似的东西时: validates_uniqueness_of :code, :scope => :parent_id

这不起作用,因为尚未保存父级。

这是我的模型:

class Category < ActiveRecord::Base
  acts_as_nested_set
  accepts_nested_attributes_for :children, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true

  default_scope :order => "lft"

  validates_presence_of :code, :name, :is_child
  validates_uniqueness_of :code, :scope => :parent_id
end

我已经想到了一种不同的方法来做到这一点,它非常接近工作,问题是我无法检查子类别之间的唯一性。

在第二个示例中,我在名为“is_child”的表单中嵌入了一个隐藏字段,以标记该项目是否为子类别。这是我的这个模型的例子:

class Category < ActiveRecord::Base
  acts_as_nested_set
  accepts_nested_attributes_for :children, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true

  default_scope :order => "lft"

  validates_presence_of :code, :name, :is_child
  #validates_uniqueness_of :code, :scope => :parent_id
  validate :has_unique_code

  attr_accessor :is_child


  private 
  def has_unique_code

    if self.is_child == "1"
      # Check here if the code has already been taken this will only work for 
      # updating existing children.
    else

      # Check code relating to other parents
      result = Category.find_by_code(self.code, :conditions => { :parent_id => nil})

      if result.nil?
        true
      else
        errors.add("code", "Duplicate found")
        false
      end
    end
  end
end

这非常接近。如果有一种方法可以检测接受嵌套属性下的 reject_if 语法中的重复代码,那么我会在那里。不过,这一切似乎都过于复杂,并且希望提出建议以使其更容易。我们希望继续在一个表单中添加类别和子类别,因为它可以加快数据输入。

更新: 也许我应该使用 build 或 before_save。

【问题讨论】:

    标签: ruby-on-rails validation nested-forms


    【解决方案1】:

    代替

    validates_uniqueness_of :code, :scope => :parent_id
    

    试试

    validates_uniqueness_of :code, :scope => :parent
    

    除此之外,您还需要在 Category 类中设置:

    has_many :children, :inverse_of => :category # or whatever name the relation is called in Child
    

    使用inverse_of会在保存前设置children变量parent,有可能会起作用。

    【讨论】:

    • 谢谢!我一直在尝试使用来自其父对象的值作为验证的一部分来验证嵌套字段。由于父对象不可用,它在新对象上失败。 :inverse_of 声明使它起作用了!
    猜你喜欢
    • 1970-01-01
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多