验证当Rails的accepts_nested_attributes_for的孩子没有父亲集

问题描述 投票:10回答:4

我想验证时访问我的孩子我的模型父模型。我发现一些有关的HAS_ONE逆属性,但我的Rails 2.3.5不承认它,所以它必须有从未进入释放。我不知道这是否正是我需要的,但。

我想验证有条件基于父属性的孩子。我的父母模型已经被创建。如果当我上的update_attributes家长孩子尚未创建,那么它没有访问父。我想知道我怎么可以访问此父。它应该很容易,像parent.build_child对子模型的PARENT_ID,为什么不建立孩子accepts_nested_attributes_for在做什么呢?

例如:

class Parent < AR
  has_one :child
  accepts_nested_attributes_for :child
end
class Child < AR
  belongs_to :parent
  validates_presence_of :name, :if => :some_method

  def some_method
    return self.parent.some_condition   # => undefined method `some_condition' for nil:NilClass
  end
end

我的方式是标准:

<% form_for @parent do |f| %>
  <% f.fields_for :child do |c| %>
    <%= c.name %>
  <% end %>
<% end %>

随着更新方法

def update
  @parent = Parent.find(params[:id])
  @parent.update_attributes(params[:parent])   # => this is where my child validations take place
end
ruby-on-rails activerecord relationships
4个回答
12
投票

我基本上使用Rails 3.2同样的问题。由于在这个问题的建议,加入inverse_of选项给母公司联想固定对我来说。

适用于您的示例:

class Parent < AR
  has_one :child, inverse_of: :parent
  accepts_nested_attributes_for :child
end

class Child < AR
  belongs_to :parent, inverse_of: :child
  validates_presence_of :name, :if => :some_method

  def some_method
    return self.parent.some_condition   # => undefined method `some_condition' for nil:NilClass
  end
end

8
投票

我有一个类似的问题:Ruby on Rails - nested attributes: How do I access the parent model from child model

这是我如何解决它最终;通过对回调设置父

class Parent < AR
  has_one :child, :before_add => :set_nest
  accepts_nested_attributes_for :child

private
  def set_nest(child)
    child.parent ||= self
  end
end

7
投票

你不能这样做,因为在内存中的孩子不知道其分配给父。它只保存后知道。例如。

child = parent.build_child
parent.child # => child
child.parent # => nil

# BUT
child.parent = parent
child.parent # => parent
parent.child # => child

所以,你可以种通过手动执行反向关联强制此行为。例如

def child_with_inverse_assignment=(child)
  child.parent = self
  self.child_without_inverse_assignment = child
end

def build_child_with_inverse_assignment(*args)
  build_child_without_inverse_assignment(*args)
  child.parent = self
  child
end

def create_child_with_inverse_assignment(*args)
  create_child_without_inverse_assignment(*args)
  child.parent = self
  child
end

alias_method_chain :"child=", :inverse_assignment
alias_method_chain :build_child, :inverse_assignment
alias_method_chain :create_child, :inverse_assignment

如果你真的觉得有必要。

附:它没有这样做,现在的原因是因为它不是太容易了。它需要被明确告知如何访问父/子在每一具体情况。与标识映射全面的做法将已经解决了这个问题,但对于较新的版本有:inverse_of解决方法。像this one一些与会者讨论了在新闻组的地方。


0
投票

检查这些网站,也许他们会帮助你...

Rails Nested Attributes Association Validation Failing

accepts_nested_attributes_for child association validation failing

http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes

看来,孩子验证成功后,轨道将分配PARENT_ID。 (父有它保存后一个id)

也许值得尝试这样的:

child.parent.some_condition

而不是self.parent.some_condition的...谁知道...

© www.soinside.com 2019 - 2024. All rights reserved.