接受嵌套属性进行验证
我正在使用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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
除此之外
,
您还需要在 Category 类中进行设置:
使用 inverse_of 将使子变量
parent
在保存之前被设置,并且有可能它会起作用。Instead of
Try
Besides that you'll need to set in the Category class:
The use of inverse_of will make the children variable
parent
be set before saving, and there is a chance it will work.