AlexeevVyacheslav
@AlexeevVyacheslav
Веб-разработчик из Иркутска

Как правильно создать массив вложенных объектов через одну форму в Rails?

Добрый день!
Имеется 2 модели: order и man.
order has_many :man
man belongs_to :order
В общем нужно в одной форме передать информацию о заказе и о нескольких людях.
Форму делаю так:
<%= form_for @order, html: { class: 'order' } do |f| %>
	<%= f.fields_for 'men[0]' do |m| %>
		<%= m.text_field :name, required: true, placeholder: 'Имя' %>
	<% end %>
	<%= f.text_field :telephone, class: 'fifty margin-right display-inline', required: true, placeholder: 'Телефон' %>
	<%= f.text_field :email, class: 'fifty display-inline', required: true, placeholder: 'Email' %>
	<%= f.fields_for 'men[0]' do |m| %>
		<%= m.text_field :age, class: 'thirty margin-right display-inline', required: true, placeholder: 'Возраст' %>
		<%= m.text_field :weight, class: 'thirty margin-right display-inline', required: true, placeholder: 'Вес' %>
		<%= m.text_field :height, class: 'thirty display-inline', required: true, placeholder: 'Рост' %>
	<% end %>

	<div class="fifty margin-right display-inline select-wrapper">
		<%= f.select :day, @days_single.map { |day| [(l day.date, :format => :short), day.id ] } %>
	</div>
	<%= f.text_field :sertnum, class: 'fifty display-inline', required: false, placeholder: 'Номер сертификата (если имеется)' %>

	<%= f.fields_for 'men[1]' do |m| %>
		<%= m.text_field :name, required: true, placeholder: 'Имя' %>
		<%= m.text_field :age, class: 'thirty margin-right display-inline', required: true, placeholder: 'Возраст' %>
		<%= m.text_field :weight, class: 'thirty margin-right display-inline', required: true, placeholder: 'Вес' %>
		<%= m.text_field :height, class: 'thirty display-inline', required: true, placeholder: 'Рост' %>
	<% end %>

	<section class="form-buttons">
		<span class="add">Добавить участника</span>	
		<span class="del">Удалить последнего участника</span>
	</section>

	<%= f.submit :submit, class: 'base-font submit', value: 'заказать' %>
	<span id="cansel-tandem" class="base-font">отменить</span>
<% end %>

И в контроллере делаю так:
private
		def order_params
			params.require(:order).permit(:telephone, :email, :sertnum, men: [])
		end

Вот только после сохранения заказа люди не появляются в своей таблице
  • Вопрос задан
  • 431 просмотр
Решения вопроса 1
Комментировать
Пригласить эксперта
Ответы на вопрос 2
viktorvsk
@viktorvsk
Нужно добавить accepts_nested_attributes_for :man (кстати, вы еще согласуйте, это man или men, т.к. у вас по тексту разные формы.

Далее, смотрите, что приходит в params, там будет не men, а men_attributes. И разрешать нужно не ничего как у вас сейчас, а конкретные атрибуты, в вашем случае: name, age, weight, height

А вообще, больше дебага: binding.pry или же byebug
Ответ написан
insiki
@insiki
broken pipe
Например так? В card_params передаю как атрибуты Card, так и Deck, и явно указываю, что мне нужно.
Правда, этот пример у меня работает наоборот - я в форме для дочернего объекта, выбираю или создаю еще и родительский. Главное понять, как делать так, чтобы в params приходило то, что нужно, и как это - то, что нужно, потом отловить и использовать.
def card_params
    params.require(:card).permit(:original_text, :translated_text, :review_date, :image, :deck_id, deck: [:title])
  end

тогда:
  • для @deck - card_params[:deck] - берём только хэш с атрибутами для :deck
  • для @card - card_params.except(:deck) - берём только хэш с атрибутами для :card (:deck исключаем)

Форма (гем Simple_Form)
<%= simple_form_for @card do |f| %>
  <%= f.input :original_text %>
  <%= f.input :translated_text %>
  <%= f.input :image %>
  <%= f.association :deck, label: "Выберите колоду" %>
  <%= f.simple_fields_for @deck do |deck| %>
    <%= deck.input :title, label: "Или создайте новую" %>
  <% end %>
  <%= f.input :review_date %>
  <%= f.button :submit %>
<% end %>

Пару полезных ссылок:
ВСЁ, ЧТО НУЖНО ЗНАТЬ О ROUTES, PARAMS И ФОРМАХ В RAILS
Создание мульти-модельных форм
Nested Model Form in Rails 4
Ну и мой, подобный вашему вопрос, на который я сам в итоге отвечаю, решение по которому отлично работает
Как создать дочерний объект при связи self reference?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы