接受嵌套属性进行验证

发布于 2024-09-29 01:46:46 字数 1988 浏览 5 评论 0原文

我正在使用Rails 2.3.8 和accepts_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:代码,:范围=> :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

这非常接近。如果有一种方法可以检测 Accepts_nested_attributes_for 下的reject_if语法中的重复代码,那么我就会在那里。但这一切似乎都过于复杂,希望得到一些建议以使其变得更容易。我们希望继续以一种形式添加类别和子类别,因为这样可以加快数据输入速度。

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

I'm using Rails 2.3.8 and accepts_nested_attributes_for.

I have a simple category object which uses awesome_nested_set to allow nested categories.

For each category I would like a unique field called code. This would be unique for the category per level. Meaning parent categories will all have unique codes and sub categories will be unique within their own parent category.

EG:

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

This works without the validation process but when I try and use something like:
validates_uniqueness_of :code, :scope => :parent_id

That will not work because the parent has not been saved yet.

Here is my model:

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

I have thought of a different way to do this and it's very close to working, problem is I cannot check for uniqueness between child categories.

In this second example I've embedded a hidden field in the form called 'is_child' to flag if the item is a sub category or not. Here is my example of this model:

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

This is very close. If there was a way to detect duplicate codes in the reject_if syntax under accepts_nested_attributes_for then I would be there. This all seems over complicated though and would like suggestions to make it easier. We would like to keep adding categories and sub categories in the one form as it speeds up data entry.

Update:
Maybe I should be using build or before_save.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凝望流年 2024-10-06 01:46:46

除此之外

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 将使子变量 parent 在保存之前被设置,并且有可能它会起作用。

Instead of

validates_uniqueness_of :code, :scope => :parent_id

Try

validates_uniqueness_of :code, :scope => :parent

Besides that you'll need to set in the Category class:

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

The use of inverse_of will make the children variable parent be set before saving, and there is a chance it will work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文