Вложенные формы не работают

#ruby-on-rails #nested-forms

#ruby-на-рельсах #вложенные формы

Вопрос:

У меня есть две модели (Bcase и C_entry), и я пытаюсь получить 10 пустых полей c_entry в каждой форме создания Bcase!

Что я сделал, так это следующее:

Модели:

bcase.rb

 class Bcase < ActiveRecord::Base
        has_many :c_entries, :dependent => :destroy
    accepts_nested_attributes_for :c_entries        
end
 

c_entry.rb

 class CEntry < ActiveRecord::Base
    belongs_to :bcase
end
 

bcase_controller.rb

   def new
        @bcase = Bcase.new
        10.times {@bcase.c_entries.build}
  end

def bcase_params
    params.require(:bcase).permit(:pimp_id, :comment_text, :status, c_entries_attributes:[:id, :description, :bcase_id])
end
 

форма (отображается в bcase -> new.html.erb)

 <%= simple_form_for :bcase, url: bcase_path do |f| %>
    <div class="form-inputs">
        <% f.simple_fields_for :c_entries do |entry| %> 
        <%= entry.input :description %>
        <% end %>
    </div>
<% end %>
 

Но если я открою представление на localhost в своем браузере, форма будет пустой. Я все протестировал и знаю, что все работает для атрибутов bcase, но не для вложенных атрибутов. Если я попытаюсь инициализировать только 1 объект, вместо этого, если 10 @bcase.c_entries.build ничего не изменится, все равно не будет отображаться ничего вложенного. Далее я попытался создать c_entries через консоль rails, и это сработало. Я также использовал эту команду Bcase.first.c_entries.build .

РЕДАКТИРОВАТЬ: Хорошо, проблема решена, но теперь в моем представлении отображается только 1 запись вместо 10! Что я делаю не так?

ПРАВКА2:

Грабли маршруты

         Prefix Verb   URI Pattern                       Controller#Action
     protocols GET    /protocols(.:format)              protocols#index
               POST   /protocols(.:format)              protocols#create
  new_protocol GET    /protocols/new(.:format)          protocols#new
 edit_protocol GET    /protocols/:id/edit(.:format)     protocols#edit
      protocol GET    /protocols/:id(.:format)          protocols#show
               PATCH  /protocols/:id(.:format)          protocols#update
               PUT    /protocols/:id(.:format)          protocols#update
               DELETE /protocols/:id(.:format)          protocols#destroy
         pimps GET    /                                 pimps#index
      new_pimp GET    /new(.:format)                    pimps#new
     edit_pimp GET    /:id/edit(.:format)               pimps#edit
          pimp GET    /:id(/.:format)                   pimps#show
               POST   /(.:format)                       pimps#create
               PUT    /:id(.:format)                    pimps#update
               PATCH  /:id(.:format)                    pimps#update
               DELETE /:id(.:format)                    pimps#destroy
   new_mepager GET    /:pimp_id/onepager/new(.:format)  mepagers#new
  edit_mepager GET    /:pimp_id/onepager/edit(.:format) mepagers#edit
       mepager GET    /:pimp_id/onepager(.:format)      mepagers#show
create_mepager POST   /:pimp_id/onepager(.:format)      mepagers#create
               PUT    /:pimp_id/onepager(.:format)      mepagers#update
               PATCH  /:pimp_id/onepager(.:format)      mepagers#update
               DELETE /:pimp_id/onepager(.:format)      mepagers#destroy
     new_bcase GET    /:pimp_id/bcase/new(.:format)     bcases#new
    edit_bcase GET    /:pimp_id/bcase/edit(.:format)    bcases#edit
         bcase GET    /:pimp_id/bcase(.:format)         bcases#show
  create_bcase POST   /:pimp_id/bcase(.:format)         bcases#create
               PUT    /:pimp_id/bcase(.:format)         bcases#update
               PATCH  /:pimp_id/bcase(.:format)         bcases#update
               DELETE /:pimp_id/bcase(.:format)         bcases#destroy
 

Simple_form_for

 <%= simple_form_for bcase_path(@pimp) do |f| %>
  <%= f.error_notification %>

<%= simple_fields_for :c_entries do |ff| %>
<div class="form-actions">
<%= ff.input :description, label: false %>
<% end %>
</div>

<% end %>
 

bcase_controller.rb

 def setall
   @pimp = Pimp.find(params[:pimp_id])
   @bcase = @pimp.bcase
end
 

Ошибка с @bcase в simple_form_for

 NoMethodError in Bcases#new 
Showing c:/Users/Public/Documents/Sites/improvement/app/views/bcases/_form.html.erb where line #1 raised: 

undefined method `bcases_path' for #<#<Class:0x53efbc0>:0x4d195d0>
 

ПРАВКА3:

Провел еще несколько тестов и включил после

 <p><%= "Nr of c-entries = #{@bcase.c_entries.size}" %></p>
 

Что возвращает мне 10 строки

 <%= @bcase.c_entries.each do |entry| %>
<%= entry.description %>
<% end %>
 

И это показывает мне 10 пустых записей! Значит, они есть, я просто почему-то не могу их разглядеть!

 [#<CEntry id: nil, bcase_id: nil, order_no: 1, description: nil, hours: nil, nrc: nil, created_at: nil, updated_at: nil>, #<CEntry id: nil, bcase_id: nil, order_no: 2, description: nil, hours: nil, nrc: nil, created_at: nil, updated_at: nil>, #<CEntry id: nil, bcase_id: nil, order_no: 3, description: nil, hours: nil, nrc: nil, created_at: nil, updated_at: nil>, #<CEntry id: nil, bcase_id: nil, order_no: 4, description: nil, hours: nil, nrc: nil, created_at: nil, updated_at: nil>, #<CEntry id: nil, bcase_id: nil, order_no: 5, description: nil, hours: nil, nrc: nil, created_at: nil, updated_at: nil>, #<CEntry id: nil, bcase_id: nil, order_no: 6, description: nil, hours: nil, nrc: nil, created_at: nil, updated_at: nil>, #<CEntry id: nil, bcase_id: nil, order_no: 7, description: nil, hours: nil, nrc: nil, created_at: nil, updated_at: nil>, #<CEntry id: nil, bcase_id: nil, order_no: 8, description: nil, hours: nil, nrc: nil, created_at: nil, updated_at: nil>, #<CEntry id: nil, bcase_id: nil, order_no: 9, description: nil, hours: nil, nrc: nil, created_at: nil, updated_at: nil>, #<CEntry id: nil, bcase_id: nil, order_no: 10, description: nil, hours: nil, nrc: nil, created_at: nil, updated_at: nil>] 
 

ПРАВКА4:

Теперь включено bcases_path в мои маршруты для отладки. Теперь мой form_for работает с @bcase, но это не решает проблемы, которые у меня есть.

ПРАВКА5:

Это каким-то образом работает с

 <%= @bcase.c_entries.each do |hallo| %>
 <%= f.simple_fields_for :c_entries, hallo do |fff| %>
    <%= fff.input :description %>
 <% end %>
<% end %>
 

Вероятно, причина в том, что указаны c_entries . Но это решение не выглядит таким уж скудным! Можно ли как-то указать это в контроллере bcase?

Комментарии:

1. Это выглядит хорошо. Уверен, что это не опечатка, вы пишете desribtion с помощью a b ?

2. О, хорошо заметил, сэр. В последнее время я изменил имя столбца с описания на описание и забыл изменить его в формах и контроллере! Я исправил это сейчас, но это все еще не работает. Я не могу объяснить себе, чего не хватает. Просмотрел различные руководства, и в них даже не так много кода, поэтому пространство для ошибок настолько мало…

Ответ №1:

Ах, нашел его! Вы забыли = в <%= . Таким образом, блок будет выполнен правильно, но не будет добавлен в форму.

Итак, напишите

 <%= simple_form_for @bcase do |f| %>
  <div class="form-inputs">
    <%= f.simple_fields_for :c_entries do |entry| %> 
      <%= entry.input :description %>
    <% end %>
  </div>
 

Комментарии:

1. Вау, чувак, ты гений: D Я твой должник! Теперь он работает отлично!

2. Хорошо, но теперь у меня проблема в том, что отображается только 1 запись, а не все 10!

3. В своем первом комментарии вы сказали, что он работает отлично, так что, я думаю, это не так 🙂 Вместо записи :bcase вам, вероятно, следует обратиться к переменной экземпляра. Итак, я обновил свой ответ. Для отладки вы могли бы включить что-то вроде <p><%= "Nr of c-entries = #{@bcase.c_entries.count}" %></p> .

4. Да, извините, я был настолько перегружен, что увидел поля формы: D Я совершенно забыл проверить, работает ли он для нескольких записей. И это не так: (Поскольку моя модель bcase вложена в другую модель, я изменил <%= simple_form_for @bcase do |f| %> на <%= simple_form_for @bcase(@pimp) do |f| %> , но это ничего не изменило. Предоставленная вами функция отладки не будет работать, поскольку c_entries не сохраняются в этом состоянии. Есть ли способ заставить его работать для подсчета не сохраненных записей? Большое спасибо!

5. Используйте size вместо count (я их смешиваю). Если вы пишете просто @bcase , работает ли это? Если вам нужен вложенный маршрут, вы должны написать simple_form_for [@pimp, @bcase] (или поменять их местами, не знаете порядок наизусть). Я бы ожидал @bcase(@pimp) , что выдаст ошибку, которая даже не ruby 🙂