accepts_nested_attributes_for验证 [英] accepts_nested_attributes_for validation
问题描述
我正在使用Rails 2.3.8并接受accepts_nested_attributes_for.
I'm using Rails 2.3.8 and accepts_nested_attributes_for.
我有一个简单的类别对象,该对象使用awesome_nested_set允许嵌套类别.
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
这无需验证过程即可工作,但是当我尝试使用类似方法时: validates_uniqueness_of:code,:scope =>:parent_id
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.
这是我的模特:
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.
在第二个示例中,我以"is_child"形式嵌入了一个隐藏字段,以标记该项目是否为子类别.这是此模型的示例:
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
这非常接近.如果有一种方法可以在accepts_nested_attributes_for下的reject_if语法中检测重复代码,那么我在那里.尽管这一切似乎都过于复杂,并且希望提出一些建议以使其变得更容易.我们希望继续以一种形式添加类别和子类别,以加快数据输入的速度.
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.
更新: 也许我应该使用build或before_save.
Update: Maybe I should be using build or before_save.
推荐答案
代替
validates_uniqueness_of :code, :scope => :parent_id
尝试
validates_uniqueness_of :code, :scope => :parent
此外,您还需要在Category类中进行设置:
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
使用inverse_of将在保存之前设置子变量parent
,这有可能会起作用.
The use of inverse_of will make the children variable parent
be set before saving, and there is a chance it will work.
这篇关于accepts_nested_attributes_for验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!