Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/53.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails a的Rails验证有很多关联_Ruby On Rails_Validation_Has Many - Fatal编程技术网

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!
...