Ruby on rails a的Rails验证有很多关联
我在验证一个有很多子关系但父母没有的关系时遇到了麻烦。但是,在创建/保存父对象时,我希望确保已保存特定的子对象(具有某些属性) 有一个Ruby on rails a的Rails验证有很多关联,ruby-on-rails,validation,has-many,Ruby On Rails,Validation,Has Many,我在验证一个有很多子关系但父母没有的关系时遇到了麻烦。但是,在创建/保存父对象时,我希望确保已保存特定的子对象(具有某些属性) 有一个父对象有许多子对象。子对象首先被持久化到数据库中,因此没有对父对象的任何引用。协会结构为: Parent - has_many :children Child - someProperty: string - belongs_to: parent 例如,有三个子对象: #1 {someProperty: "bookmark", parent: n
父对象有许多子对象。子对象首先被持久化到数据库中,因此没有对父对象的任何引用。协会结构为:
Parent
- has_many :children
Child
- someProperty: string
- belongs_to: parent
例如,有三个子对象:
#1 {someProperty: "bookmark", parent: nil}
#2 {someProperty: "history", parent: nil }
#2 {someProperty: "window", parent: nil }
仅当父对象包含具有someProperty历史记录
和窗口
的子对象时,该父对象才有效
我正在控制器内将父级设置为:
p = Parent.new(params[:data])
for type in %w[bookmark_id history_id window_id]
if !params[type].blank?
p.children << Child.find(params[type])
end
end
// save the parent object p now
p.save!
p=Parent.new(参数[:数据])
用于键入%w[书签\u id历史记录\u id窗口\u id]
如果!参数[type]。是否为空?
p、 children首先,如果希望在不使用父id的情况下保存子项,那么这样做没有意义
p = Parent.new(params[:data])
for type in %w[bookmark_id history_id window_id]
if !params[type].blank?
p.children << Child.find(params[type])
end
end
p=Parent.new(参数[:数据])
用于键入%w[书签\u id历史记录\u id窗口\u id]
如果!参数[type]。是否为空?
p、 孩子们不知道你为什么要做这样的事情,但无论如何,这样做怎么样
class Parent < ActiveRecord::Base
CHILDREN_TYPES = %w[bookmark_id history_id window_id]
CHILDREN_TYPES.each{ |c| attr_accessor c }
has_many :children
before_validation :assign_children
validate :ensure_has_proper_children
private
def assign_children
CHILDREN_TYPES.each do |t|
children << Child.find(send(t)) unless send(t).blank?
end
end
def ensure_has_proper_children
# Test if the potential children meet the criteria and add errors to :base if they don't
end
end
如您所见,我首先将所有逻辑移到了模型中。然后,拯救儿童有两个步骤。首先,我们将子项分配给父项,然后验证它们是否满足所需的条件(在此处插入逻辑)
对不起,太短了。如果有必要,我会回答更多的问题。谢谢你的回答。我并不特别想保存没有父id的子项,只是在这个过程中总是首先创建子项。在那一点上我不会有任何关于父母的信息。家长的信息将在稍后的HTTP请求中提供。子对象是一次性的,我不在乎它们是否有父对象,因为cron作业会定期清理它们。从技术上讲,我可以使用会话,但这肯定会杀死服务器,因为子对象确实很重,所以我选择将它们直接存储在db中。好的,我现在明白你的意思,我将编辑我的答案,我喜欢这种方法,因为它将逻辑保留在模型中。发送(t)函数在这里做什么?它是在父对象上调用的吗?是的,因为我们动态地将子类型定义为父对象的访问器(属性),所以我们也需要动态地访问它们。这就是为什么我们需要对父对象调用send方法。
transaction do
p = create_parent
p.children << child1
p.children << child2
end
p = Parent.new(params[:data])
for type in %w[bookmark_id history_id window_id]
if !params[type].blank?
p.children << Child.find(params[type])
end
end
children = []
for type in %w[bookmark_id history_id window_id]
if !params[type].blank?
children << Child.find(params[type])
end
end
if children.size >= 2
p = Parent.create!(params[:data])
children.each {|child| p.children << child}
end
class Parent < ActiveRecord::Base
CHILDREN_TYPES = %w[bookmark_id history_id window_id]
CHILDREN_TYPES.each{ |c| attr_accessor c }
has_many :children
before_validation :assign_children
validate :ensure_has_proper_children
private
def assign_children
CHILDREN_TYPES.each do |t|
children << Child.find(send(t)) unless send(t).blank?
end
end
def ensure_has_proper_children
# Test if the potential children meet the criteria and add errors to :base if they don't
end
end
...
p = Parent.new(params[:data])
p.save!
...