Я пытаюсь получить доступ к своей родительской модели в моей дочерней модели при проверке. Я нашел что-то об обратном свойстве на has_one, но мои направляющие 2.3.5 не распознают его, таким образом, это никогда, должно быть, не превращало его в выпуск. Я не уверен, точно ли это, в чем я нуждаюсь все же.
Я хочу проверить ребенка условно на основе родительских атрибутов. Моя Родительская модель была уже создана. Если ребенок не был создан, когда я update_attributes на родителе, то он не имеет доступа к родителю. Я задаюсь вопросом, как я могу получить доступ к этому родителю. Это должно быть легко, что-то как родитель 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
Посмотрите эти сайты, может быть, они вам помогут...
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
похоже, rails присваивает parent_id после успешной проверки child. (так как родитель имеет id после сохранения)
возможно, стоит попробовать следующее:
child.parent.some_condition
вместо self.parent.some_condition ... кто знает...
Вы не можете этого сделать, потому что дочерний элемент в памяти не знает родителя, которому он назначен. Он узнает об этом только после сохранения. Например.
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
Если вы действительно считаете это необходимым.
P.S. Причина, по которой он не делает этого сейчас, в том, что это не слишком просто. Ему нужно явно указать, как получить доступ к родителям/детям в каждом конкретном случае. Комплексный подход с identity map решил бы эту проблему, но для новой версии есть :inverse_of
обходной путь. Некоторые обсуждения, подобные этому, имели место в группах новостей.