I'm new to rails or coding in general, trying to learn by creating a simple app, I'm not sure if it's silly to ask, but I tried really finding a concrete answer to the problem and failed each time for days, I would appreciate if someone can help me on this;
I have a "Plane" model which has "PlaneModel", "Xroutes" and "Staffs" attributes. Each 3 attrs, are pre-created, have their own tables, and upon a new instance of plane creation you just select through available items via "collection_select". Code for Plane.rb;
class Plane < ApplicationRecord
belongs_to :plane_model
belongs_to :xroute
has_many :staffs
accepts_nested_attributes_for :staffs
end
Now, because of the db relations, Planes table have a Planemodel_id, Xroute_id but not Staff_id. There lies the problem, because when I try to create an instance of a plane, "collection_select" easily works for the first 2 attrs, assigning Planemodel_id and Xroute_id respectively. For staffs though what I want to achieve is, after creation of each plane, assigning that plane_id on the corresponding staff row in Staffs table. Code for Staff.rb;
class Staff < ApplicationRecord
belongs_to :hub, optional: true
belongs_to :plane, optional: true
end
Below is the _form for planes;
<%= 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 %>
Inside the plane controller new & create functions and params function to whitelist attributes;
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
Here is the visual representation of what's happening;
When submitted, a new instance is successfully created.
Here is the index page for Planes, as you see PlaneModel and Xroute are there.
When I go to staffs page though, instead of putting created plane's id in the selected staffs "plane_id" field, it just throws additional 3 staff instances without any more information on it.
Staff index page showing, newly created empty staff instances.
Like I said maybe it's a simple thing but I'm missing something for sure, appreciate all the help & suggestions.
Thanks,
accepts_nested_attributes_for :staffs
allows you to create a staffs instances together with a plane, inside the same form. But as I can see you want only to select existing staff, am I right? You need to change you form:
<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
and remove 3.times { @plane.staffs.build }
from new action