Rails 5-form_with -fields_for在创建父项时分配嵌套属性。

时间:2018-12-13 15:44:32

标签: ruby-on-rails nested-attributes fields-for

我一般都不熟悉Rails或编码,试图通过创建一个简单的应用程序来学习,我不确定问这是否很愚蠢,但是我试图真正找到问题的具体答案,但每次都失败天,如果有人可以帮助我,我将不胜感激;

我有一个具有“ PlaneModel”,“ Xroutes”和“ Staffs”属性的“ Plane”模型。每个3个attrs都是预先创建的,具有自己的表,在创建平面的新实例上,您只需通过“ collection_select”通过可用项进行选择。 Plane.rb的代码;

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

现在,由于存在数据库关系,Planes表具有Planemodel_id,Xroute_id,但不是 Staff_id。这里存在问题,因为当我尝试创建平面的实例时,“ collection_select”可以轻松地用于前两个属性,分别分配Planemodel_id和Xroute_id。对于职员来说,虽然我想实现的目标是,在创建每个平面之后,在Staffs表中相应的职员行上分配那个plane_id。 Staff.rb的代码;

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

下面是飞机的_form;

<%= 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 %>

在平面控制器new内以及创建函数和params函数以将属性列入白名单;

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

这是正在发生的事情的视觉表示;

Form for creating new plane instance, PlaneModel, Xroute and 3 staff members are selected from dropdown lists.

When submitted, a new instance is successfully created.

Here is the index page for Planes, as you see PlaneModel and Xroute are there.

但是,当我转到人员页面时,与其将创建的飞机的ID放置在选定的人员“ plane_id”字段中,它只是抛出了另外3个人员实例而没有任何更多信息。

Staff index page showing, newly created empty staff instances.

就像我说的那样,这可能很简单,但是我肯定会丢失一些东西,感谢所有帮助和建议。

谢谢

1 个答案:

答案 0 :(得分:0)

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>

参数:

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

并从新操作中删除3.times { @plane.staffs.build }