Направляющие accepts_nested_attributes_for ребенок не имеют родительского набора при проверке

Я пытаюсь получить доступ к своей родительской модели в моей дочерней модели при проверке. Я нашел что-то об обратном свойстве на 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
10
задан brad 9 February 2010 в 04:27
поделиться

2 ответа

Посмотрите эти сайты, может быть, они вам помогут...

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 ... кто знает...

0
ответ дан 3 December 2019 в 15:51
поделиться

Вы не можете этого сделать, потому что дочерний элемент в памяти не знает родителя, которому он назначен. Он узнает об этом только после сохранения. Например.

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 обходной путь. Некоторые обсуждения, подобные этому, имели место в группах новостей.

7
ответ дан 3 December 2019 в 15:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: