Динамические формы с Cocoon - неопределенный метод отражения_on_association для NilClass:Class:

Я использую камень кокона, чтобы построить динамическую форму, в которую я могу добавить новые текстовые поля. Я читал других людей ту же проблему, но я не знаю, что я делаю неправильно, я знаю, что это должно быть что-то с ассоциациями, но я, кажется, не понимаю.

Итак, это мои модели:

class MonitorCategory < ActiveRecord::Base

  validates :operation, presence: true
  attr_accessor :oid, :oid2, :oids, :snmp_oper, :custom_tab_name, :custom_tab_unit, :redfish, :ipmi
  has_many :oids
  has_and_belongs_to_many :sensors

  accepts_nested_attributes_for :oids

class Oid < ActiveRecord::Base
  belongs_to :monitor_category
 end

И моя форма:

<%= simple_form_for(:monitor_category, url: create_monitor_category_path, :html => { :remote => true, :method => :post }) do |f| %>
<div id='oids'>
    <%= f.simple_fields_for :oids do |oid| %>
    <%= render 'oids_fields', :f => oid %>
    <% end %>
    <div class='links'>
      <%= link_to_add_association 'add oid', f, :oids %>
    </div>
</div>

с частичным _oids_fields.html.erb:

<div class='nested-fields'>
<%= f.input :oids %>
</div>

Что я делаю неправильно? Я получаю неопределенный метод отражения_on_association для NilClass:Class:. С формой все в порядке, так как я смотрел на страницу кокона, и у меня тот же синтаксис, так что я предполагаю, что это должно быть что-то с ассоциациями, но я действительно не знаю, я вроде новичок в мире рельсов. Может быть, так как он говорит nilClass, мне нужно создать контроллер для модели Oid, в которой я делаю новый метод или что-то? Я заблудился.

Видимо это тоже не работает, у меня та же ошибка:

class OidController < ApplicationController

  def new
    @oid = Oid.new
  end

end  

спасибо за каждый ответ.

редактировать: просто чтобы быть более понятным, потому что я очень запутался.

Прежде чем пытаться реализовать эту динамическую форму, у меня уже есть форма, которая работает правильно. Например, два последних поля:

      <div class="col-md-12">
        <%= f.input :oid, label: 'SNMP OID', as: :search, placeholder: 'Output stored in var1.', required: false, novalidate: true, input_html: {data: { autocomplete_source: get_oids_path }} %>
      </div>
      <div class="col-md-12">
        <%= f.input :oid2, label: 'SNMP OID 2', as: :search, placeholder: 'Output stored in var2.', required: false, novalidate: true, input_html: {data: { autocomplete_source: get_oids_path }} %>
      </div>

Таким образом, здесь в основном сохраняются значения, введенные для атрибута:oid и:oid2 из модели.

но вместо того, чтобы иметь эти два поля, я хочу иметь только одно и добавлять больше динамически, чтобы я мог ввести, например, 6 значений и сохранить их все в атрибуте:oids. Так как я сохранял значение в атрибуте, я не знаю, нужно ли мне создавать модель для Oid, как это делал раньше, и делать ее принадлежащей monitor_category. Или, если я могу просто добавить атрибут :oids к контроллеру и сохранить все значения в этой переменной.

2 ответа

Проблема в этой линии

simple_form_for(:monitor_category, url: create_monitor_category_path, :html => { :remote => true, :method => :post }) do |f| 

Это создает форму для MonitorCategory но не устанавливает объект. Поэтому, когда вы тогда позвоните f.simple_fields_for нет объекта для перебора ассоциаций.

Обычно в контроллере вы устанавливаете @monitor_category переменная экземпляра, которая либо устанавливается на существующий экземпляр (при редактировании), либо на вновь созданный элемент.

И тогда вы можете написать:

simple_form_for(@monitor_category, :html => { :remote => true, :method => :post }) do |f| 

Rails достаточно умен, чтобы вывести url из объекта, он либо создаст новый, либо обновит существующий.

Это достаточно ясно?

Я думаю, это потому, что ваша форма для monitor_category и URL-адрес указывает на create_monitor_category_path, Но вы показываете нам OidController, Вам нужно что-то вроде:

class MonitorCategoryController < ApplicationController
  def new
    @monitor_category = MonitorCategory.new
    @monitor_category.oids.build
  end
end

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

Другие вопросы по тегам