Задать вопрос
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

Вот только после сохранения заказа люди не появляются в своей таблице
  • Вопрос задан
  • 436 просмотров
Подписаться 3 Оценить Комментировать
Решения вопроса 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?
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы