#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
с помощью ab
?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 🙂