Rails 5 - form_with - fields_for назначать вложенные атрибуты при создании родительских элементов. - PullRequest
0 голосов
/ 13 декабря 2018

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

У меня есть модель "Плоскость", которая имеет атрибуты "PlaneModel", "Xroutes" и "Staffs".Каждые 3 атрибута предварительно созданы, имеют свои собственные таблицы, и при новом экземпляре создания плоскости вы просто выбираете доступные элементы через «collection_select».Код для Plane.rb;

class Plane < ApplicationRecord
  belongs_to :plane_model
  belongs_to :xroute    
  has_many :staffs
  accepts_nested_attributes_for :staffs
end

Теперь, из-за связей db, таблица Planes имеет Planemodel_id, Xroute_id, но не Staff_id.В этом и заключается проблема, потому что когда я пытаюсь создать экземпляр плоскости, «collection_select» легко работает для первых двух атрибутов, присваивая Planemodel_id и Xroute_id соответственно.Однако для посохов я хочу после создания каждого самолета назначить этот plane_id в соответствующей строке посоха в таблице Staffs.Код для Staff.rb;

class Staff < ApplicationRecord
  belongs_to :hub, optional: true
  belongs_to :plane, optional: true
end

Ниже приведена форма _ для плоскостей;

<%= form_with(model: plane, local: true) do |form| %>
  <div class="control-group">
    <%= form.label :plane_model_id %>
    <div class="controls">
      <%= collection_select( :plane, :plane_model_id, PlaneModel.all, :id, :name, {}, { :multiple => false } ) %>
    </div>
  </div>

  <div class="control-group">
    <%= form.label :xroute_id %>
    <div class="controls">
      <%= collection_select( :plane, :xroute_id, Xroute.all, :id, :name, {}, { :multiple => false } ) %>
    </div>
  </div>

  <%= form.fields_for :staffs do |staff| %>
    <div class="control-group">
      <%= staff.label :staff_id %>
      <div class="controls">
        <%= staff.collection_select( :plane_id, Staff.all, :id, :name, { :multiple => false } ) %>
      </div>
    </div>
  <% end %>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

Внутри контроллера плоскости добавлены новые функции и созданы функции для атрибутов белого списка;

def new
  @plane = Plane.new
  3.times { @plane.staffs.build }
end

def create
  @plane = Plane.new(plane_params)    
  respond_to do |format|
    if @plane.save
      format.html { redirect_to @plane, notice: 'Plane was successfully created.' }
      format.json { render :show, status: :created, location: @plane }
    else
      format.html { render :new }
      format.json { render json: @plane.errors, status: :unprocessable_entity }
    end
  end
end

def plane_params
  params.require(:plane).permit(:plane_model_id, :xroute_id, staffs_attributes: [:id, :staff, :plane_id])
end

Вот визуальное представление о том, что происходит;

Форма для создания нового экземпляра самолета, PlaneModel, Xroute и 3 сотрудника выбираются из выпадающих списков.

Когда отправлено, новый экземпляр успешно создан.

Вот страница индекса для Плоскостей, поскольку вы видите, что там есть PlaneModel и Xroute.

Когда я захожу на страницу сотрудников, вместо того, чтобы помещать идентификатор созданного самолета в поле «идентификатор_пункта» выбранного персонала, он просто выбрасывает дополнительные 3 экземпляра персонала без дополнительной информации.

Персоналстраница указателя показывает, недавно созданные пустые экземпляры персонала.

Как я уже сказал, может быть, это простая вещь, но я что-то упускаю наверняка, оцените всю помощь и предложения.

Спасибо

1 Ответ

0 голосов
/ 13 декабря 2018

accepts_nested_attributes_for :staffs позволяет создавать экземпляры посохов вместе с плоскостью внутри одной формы.Но, как я понимаю, вы хотите только выбрать существующий персонал, я прав?Вам нужно изменить форму:

<div class="control-group">
  <%= form.label :staff_ids %>
  <div class="controls">
    <%= form.collection_select( :staff_ids, Staff.all, :id, :name, {}, { multiple: true } ) %>
  </div>
</div>

params:

def plane_params
  params.require(:plane).permit(:plane_model_id, :xroute_id, staff_ids: [])
end

и удалить 3.times { @plane.staffs.build } из нового действия

...