Динамические формы с 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
Это инициализирует родительский объект, а затем создает дочернюю ассоциацию. Вам нужно создать хотя бы одного дочернего элемента, чтобы поля отображались при использовании полей для.