bra*_*rad 10 activerecord ruby-on-rails relationships
我在验证时试图在我的子模型中访问我的父模型.我在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
Run Code Online (Sandbox Code Playgroud)
我的表格是标准的:
<% form_for @parent do |f| %>
<% f.fields_for :child do |c| %>
<%= c.name %>
<% end %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
使用更新方法
def update
@parent = Parent.find(params[:id])
@parent.update_attributes(params[:parent]) # => this is where my child validations take place
end
Run Code Online (Sandbox Code Playgroud)
Hen*_*k N 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
Run Code Online (Sandbox Code Playgroud)
我遇到了类似的问题:Ruby on Rails - 嵌套属性:如何从子模型访问父模型
这就是我最终解决的问题; 通过在回调上设置父级
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
Run Code Online (Sandbox Code Playgroud)
您不能这样做,因为内存中的子节点不知道它所分配的父节点.它只能在保存后知道.例如.
child = parent.build_child
parent.child # => child
child.parent # => nil
# BUT
child.parent = parent
child.parent # => parent
parent.child # => child
Run Code Online (Sandbox Code Playgroud)
因此,您可以通过手动执行反向关联来强制执行此行为.例如
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
Run Code Online (Sandbox Code Playgroud)
如果你真的觉得有必要.
PS它现在不这样做的原因是因为它不太容易.需要明确告知如何在每种特定情况下访问父/子.使用身份图的综合方法可以解决它,但对于较新的版本,有:inverse_of解决方法.像这样的一些讨论发生在新闻组上.
检查这些网站,也许它们会帮助你......
Accept_nested_attributes_for 子关联验证失败
http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes
看起来,rails 会在子验证成功后分配parent_id。(因为父级在保存后有一个id)
也许值得尝试这个:
child.parent.some_condition
Run Code Online (Sandbox Code Playgroud)
而不是 self.parent.some_condition ...谁知道...
| 归档时间: |
|
| 查看次数: |
6113 次 |
| 最近记录: |