代码之家  ›  专栏  ›  技术社区  ›  map7

接受\嵌套的\属性\进行验证

  •  4
  • map7  · 技术社区  · 14 年前

    我正在使用Rails 2.3.8,并接受“嵌套的”属性。

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

    对于每个类别,我希望有一个名为“代码”的唯一字段。这对于每个级别的类别是唯一的。这意味着父类别都有唯一的代码,子类别在其自己的父类别中是唯一的。

    如:

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

    这不需要验证过程,但当我尝试使用以下内容时: 验证: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中检测重复的代码,如果语法在accepts-nested-attributes下,那么我会在那里。这一切似乎太复杂了,但希望有建议使之更容易。我们希望在一个表单中继续添加类别和子类别,因为这样可以加快数据输入的速度。

    更新: 也许我应该使用build或者在保存之前。

    1 回复  |  直到 14 年前
        1
  •  4
  •   hsgubert    12 年前

    而不是

    validates_uniqueness_of :code, :scope => :parent_id
    

    尝试

    validates_uniqueness_of :code, :scope => :parent
    

    此外,您还需要在类别类中设置:

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

    使用will使子变量 parent 在存钱前做好准备,这是一个成功的机会。