Вложенная простая форма в Rails4 - имеет много сквозных, сохранение нескольких записей

У меня есть стандартный has_many через отношения. У людей много орков через таблицу соединений. Взаимодействия - это всего лишь таблица и модель; нет контроллера или просмотров.

Используя простой шаблон в Rails 4, я хочу сделать форму на странице людей, чтобы выбрать несколько орков из пула всех орков. После отправки я хочу, чтобы он создавал/обновлял столько записей в таблице взаимодействия, каждый с идентификатором человека, и было выбрано столько орков. :

Обозначение списка АКА

  1. Сделайте форму с одного конца (человека)
  2. Список всех орков в форме
  3. Выберите несколько орков из этого списка
  4. Сохраните столько записей в таблице взаимодействий с помощью human_id и orc_id поскольку из этого списка выбраны орки. (Человеческий_ид будет таким же в этих записях, поскольку он начинался с данной страницы человеческой формы)

Я буду кодировать как можно большую часть всей истории. Пожалуйста, не стесняйтесь просить разъяснений и исправить что-то не так для этого.

таблицы

humans
 integer "id"

interactions
 integer "human_id"
 integer "orc_id"


 index ["human_id", "orc_id"] 
 # This is the primary key. no normal id.
 # Is it better to have a primary id for this join table, or does it not matter?

orcs
 integer "id"

модели

/models/human.rb

class Human < ActiveRecord::Base
 has_many :interaction
 has_many :orcs, through: :interactions

 accepts_nested_attributes_for :interactions
end

/models/interaction.rb

# Purely a join model and table. No controller, no scaffold.
class Interaction
<p>/models/orc.rb</p> <pre class="prettyprint linenums">class Orc&lt; ActiveRecord::Base has_many :interactions has_many :humans, through: :interactions end</pre> <p> <span>Контроллеры</span></p> <p>/controllers/humans_controller.rb</p> <pre class="prettyprint linenums">class HumansController &lt; ApplicationController before_action :set_human, only: [:show, :edit, :update, :destroy] before_action :build_interaction, only: [:new, :edit] private def set_human @human = Human.find(params[:id]) end def human_params params.require(:human).permit( interaction_attributes: [:human_id, :orc_ids, # Is plural here correct? :_destroy] ) end def build_interaction @interaction = @human.interactions.build # Is the human instance variable valid here? # How many interactions are being built here? # How do I ensure there are as many interaction builds as there will be selected orcs (i.e. as many interaction records to be saved or updated)? end end</pre> <p>/controllers/orcs_controller.rb</p> <pre class="prettyprint linenums">class OrcsController &lt; ApplicationController before_action :set_orc, only: [:show, :edit, :update, :destroy] private def set_orc @orc = Orc.find(params[:id]) end def orc_params params.require(:orc).permit() end end</pre> <p> <span>Просмотры</span></p> <p>/views/humans/_form.html.haml</p> <pre class="prettyprint linenums">= simple_form_for(@human, html: { multipart: true }) do |f| = f.simple_fields_for :interactions do |i| = i.hidden_field :human_id, value: @human.id = i.association :orc, collection: Orc.all ^ # Should this be :orc_id? # Does this code automatically extract the orc_id when saving to the interactions table?</pre> <p> Спасибо.</p> <p> Что мне не хватает? когда я отправляю, я подтвердил, что нет записи, созданной в таблице соединений.</p> <p> Я думаю, что некоторые из проблем</p> <ol> <li> создавая несколько записей, повторно использующих одно скрытое поле ввода.</li> <li> получение списка орков, когда таблица взаимодействий должна быть сингулярной orc (поскольку она была определена с помощью sort_to: orc в модели взаимодействия)</li> </ol> <p> Кроме того, где я могу узнать больше о том, как работает множественная форма идентификаторов модели (т. <code>orc_ids Просто использовать orc_ids вместо orc_id и какие конкретные последствия влекут за собой)?

1 ответ

Оказывается, что с simple_form это на самом деле довольно просто (кто знал?). Он обрабатывает магию всех промежуточных таблиц (вместе с Rails awesomeness). Все, что вам нужно сделать, это следующее:

= simple_form_for(@human, html: { Pmultipart: true }), do |f|
 = f.association :orcs

Я действительно не использую HAML, поэтому я не уверен в этой запятой, прежде чем do |f| , Вот что я пытаюсь сказать в ERB HTML

<%= simple_form_for(@human) do |f| %>
 <%= f.association :orcs %>
<% end %>

Затем в вашем контроллере дезинфицирующее средство:

def orc_params
 params.require(:orc).permit(orc_ids: [])
end

И, наконец, в вашей модели:

class Human < ActiveRecord::Base
 ...
 accepts_nested_attributes_for :orcs
end

И это! Он автоматически создаст объекты объединения. Разве вы не просто любите магию?

Это создаст поле с несколькими выборами, заполненное всеми орками. Вы можете легко изменить это на флажки, используя f.association :orcs, as: :check_boxes.

licensed under cc by-sa 3.0 with attribution.