My goal is to present a select form to the user, where they can select multiple options. The edit form is for a SiteGroup which is a group of an object Site.
The form should display all existing sites and highlight those which are already selected.
However the updating works, but the sites do not update.
site_group.rb
class SiteGroup < ActiveRecord::Base
has_and_belongs_to_many :sites
accepts_nested_attributes_for :sites
end
site_groups_controller.rb
class SiteGroupsController < ApplicationController
before_action :set_site_group, only: [:show, :edit, :update, :destroy]
# GET /site_groups
# GET /site_groups.json
def index
@site_groups = SiteGroup.all
end
# GET /site_groups/1
# GET /site_groups/1.json
def show
end
# GET /site_groups/new
def new
@site_group = SiteGroup.new
end
# GET /site_groups/1/edit
def edit
end
# POST /site_groups
# POST /site_groups.json
def create
@site_group = SiteGroup.new(site_group_params)
respond_to do |format|
if @site_group.save
format.html { redirect_to @site_group, notice: 'Site group was successfully created.' }
format.json { render :show, status: :created, location: @site_group }
else
format.html { render :new }
format.json { render json: @site_group.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /site_groups/1
# PATCH/PUT /site_groups/1.json
def update
respond_to do |format|
if @site_group.update(site_group_params)
format.html { redirect_to @site_group, notice: 'Site group was successfully updated.' }
format.json { render :show, status: :ok, location: @site_group }
else
format.html { render :edit }
format.json { render json: @site_group.errors, status: :unprocessable_entity }
end
end
end
# DELETE /site_groups/1
# DELETE /site_groups/1.json
def destroy
@site_group.destroy
respond_to do |format|
format.html { redirect_to site_groups_url, notice: 'Site group was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_site_group
@site_group = SiteGroup.find(params[:id])
@sites = Site.all
end
# Never trust parameters from the scary internet, only allow the white list through.
def site_group_params
params.require(:site_group).permit(
:name,
:library,
sites: [:id]
)
end
end
_form.html.erb for SiteGroup
<%= form_for(@site_group) do |f| %>
<% if @site_group.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@site_group.errors.count, "error") %> prohibited this site_group from being saved:</h2>
<ul>
<% @site_group.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
# the @sites will also print the class, I would like to show the :name of the Site
<%= f.select :sites,
@sites,
{},
{multiple: true, size: 10}
%>
<div class="field">
<%= f.label :library %>
<%= f.text_field :library %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
How can I get the update to work and to show the name if the sites in the select field?
To show the names of the sites, use the collection select tag as follow:
<%= f.fields_for :sites do |s| %>
<%= s.collection_select :sites,
@sites,
:id,
:name,
{},
{multiple: true, size: 10}
%>
<% end %>
This is according to the documentation on collection select.
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {}) public
You can also check this other answer for more information.