Unable to access Multiselect Values in Ruby on Rails Controller - ruby-on-rails

I'm trying to implement a multi-select for a many to many relationship in Ruby on Rails, however I'm unable to access the array of strings representing the selected User Ids in the user_ids field.
The following is my project_params after clicking update
"project"=>{"name"=>"Project Name",
"client"=>"Client X", "project_url"=>""},
"user_ids"=>["2", "3", "4", "5"], "commit"=>"Update Project", "id"=>"1"}
The following is my ProjectsController code
def update
puts project_params[:user_ids=>[]]
respond_to do |format|
if #project.update(project_params)
format.html { redirect_to #project, notice: 'Project was successfully updated.' }
format.json { render :show, status: :ok, location: #project }
else
format.html { render :edit }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
def project_params
params.require(:project).permit(:id, :name, :client, :project_url, :user_ids => [])
end
The line puts project_params[:user_ids=>[]] prints a blank line. I've also tried puts project_params[:user_ids] and puts project_params[:user_ids[]] - none of which work
The following is my _form.html.erb Code
<%= select_tag "user_ids",
options_from_collection_for_select(User.all, "id", "name", #project.user),
{ :multiple => true, :size =>10}
%>

The select tag will use the first argument as the key. Hence the values is located on:
params[:user_ids]
or if you are using form builder
<%= form_for #project do |f| %>
<%= f.select :user_ids,
options_from_collection_for_select(User.all, "id", "name", #project.user),
{ :multiple => true, :size =>10}
%>
<% end %>
then it will be available in project_params

Related

Rails polymorphic association: Struggling with form to input tags

I have a model with movies and actors and I want both to be taggeable. I know there's a gem for that but I thought I'd teach myself polymorphic associations :)
Basic functionality works (I can do stuff like amovie.tags.create etc...) but now I want forms for movies and actors where tags can be selected and deselected.
Problem : I cannot deselect a tag:
While selecting a tag (that exists) works, when I deselect a tag, I get an error. Here's the relevant code:
Movie Form:
<%= form.collection_select(:tag_ids, Tag.order(:name), :id, :name, {}, { class: 'selectize-tag', multiple: true }) %>
movies controller - update section as well as movies_params private function:
def update
respond_to do |format|
if #movie.update(movie_params)
format.html { redirect_to #movie, notice: "Movie was successfully updated." }
format.json { render :show, status: :ok, location: #movie }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #movie.errors, status: :unprocessable_entity }
end
end
end
def movie_params
params.require(:movie).permit(:title, :runtime, :country, :release_year, :sort_title, tag_ids: [])
end
Error I get:
Mysql2::Error: Column 'taggeable_id' cannot be null
Params - I think the problem is the line that has tag IDs and one of them is ""
{"_method"=>"patch",
"authenticity_token"=>"[FILTERED]",
"movie"=>
{"title"=>"The Avengers",
"sort_title"=>"Avengers",
"release_year"=>"2012",
"country"=>"US",
"runtime"=>"143",
"tag_ids"=>["", "3"]},
"commit"=>"Update Movie",
"id"=>"48"}
So not sure what I need to do for that empty tag id there to not be submitted but rather to trigger "remove tag with ID xyz from movie abc?

Rails - problema con il salvataggio di un array tramite check_boxes

I am trying to create a register for a school, I got to the point where I had to create the class lessons and save presences/absences in it.
I'm thinking about making appear a collection_check_boxes which gathers all the students who belong to the class we are recording the lesson for.
At this point the checkbox is properly displayed on the vista, but it doesn't fill the array student_id of Lesson when it's created.
Il controller
def new
#lesson = Lesson.new
#group_id = params[:group_id]
#students = Student.where(:group_id => #group_id)
end
def create
#lesson = Lesson.new(lesson_params)
respond_to do |format|
if #lesson.save
format.html { redirect_to #lesson, notice: 'Lesson was successfully created.' }
format.json { render :show, status: :created, location: #lesson }
else
format.html { render :new }
format.json { render json: #lesson.errors, status: :unprocessable_entity }
end
end
end
def lesson_params
params.require(:lesson).permit(:date, :starts_at, :finishes_at, :materials, :areas, :homework, :group_id, :student_id)
end
While the view that calls the check_boxes
<div class="field">
<%= form.collection_check_boxes :student_id, Student.where(:group_id => #group_id).order(name: :asc), :id, :name, {}, { multiple: true } %>
</div>
Can anybody help me, please?
Try this
<%= form.collection_check_boxes :student_ids, Student.where(:group_id => #group_id).order(name: :asc), :id, :name %>
ok, i solved
I had to declare the array between the parameters allowed in the controller
def lesson_params
params.require(:lesson).permit(:date, :starts_at, :finishes_at, :materials, :areas, :homework, :group_id, :student_id => [] )
end
i hope this can help someone else.

The current value is not saved after a re edition

I have a problem with my re-edition. Let me explain it : When I edit and update an object current value is ok in my show view. But if i re-edit current value isn't the last selected.
Problem is only with checkbox or select.
My form
<%= f.fields_for :situations do |s| %>
<p><label for="plage">Plage</label>
<%= s.select :plage?, ["", "oui","non"] %> à <%= s.select :distanceplage?, ["", "moins de 1", "2","3", "4", "5 et plus"] %> km</p>
<% end %>
controller
def edit
end
def update
#camping = Camping.find(params[:id])
respond_to do |format|
if #camping.update(camping_params)
format.html { redirect_to #camping, notice: 'Camping was successfully updated.' }
format.json { render :show, status: :ok, location: #camping }
else
format.html { render :edit }
format.json { render json: #camping.errors, status: :unprocessable_entity }
end
end
end
How i can fix it ? Thanks for your help !
Ok so after some search solution is this :
:include_blank => true
so my view looks like this
<p><label for="plage">Plage</label>
<%= s.select :plage, ["oui","non"], :include_blank => true %> à <%= s.text_field :distanceplage %> km</p>

foreignkey not saved in nested model rails

i have two tables in my application
rfp.rb
has_many :rfp_hors
attr_accessible :rfp_hors_attributes
accepts_nested_attributes_for :rfp_hors, :allow_destroy => true
rfp_hor.rb
attr_accessible :numberofmenu_est_hours,
:numberofmenu_act_hours,
:browser_est_hours,
:browser_act_hours,
:numberofpage_est_hours,
:numberofpage_act_hours,
:rfp_id
belongs_to :rfp
when i submit rfp_hors the parameter shows as follows in console
Parameters: {"rfp_hor"=>{"ecommerce_est_hours"=>"7", "rfp_id"=>"13", "designcomplexity_est_hours"=>"3", "browser_est_hours"=>"4", "framworks_est_hours"=>"5", "cms_est_hours"=>"6"}, "utf8"=>"✓", "commit"=>"Create Rfp hor", "authenticity_token"=>"XXgQlufpBP2lvcde/EiFIx93aM5Ov47MNFqsCkLun2Y="}
and controller
rfps.rb
def show
#rfp = Rfp.find(params[:id])
#rfp_hor = RfpHor.new
end
rfp_hors.rb
def create
#rfp_hor = RfpHor.create(params[:rfp_hor])
respond_to do |format|
if #rfp_hor.save
format.html { redirect_to rfp_url(#rfp_hor.rfp_id), :notice => 'rfp hour was successfully created.' }
format.json { render :json => #rfp_hor, :status => :created, :location => #rfp_hor }
else
format.html { render :action => "new" }
format.json { render :json => #rfp_hor.errors, :status => :unprocessable_entity }
end
end
end
every thing saves fine in databse aceept rfp_id in rfp_hors
any help would be great thanks in advance
your problem is because you are initializing the variable #rfp_hor as new independent object in the rfps controller when would you initialize only the varbiale #rfp, you could try of this way:
def edit
#rfp = Rfp.find(params[:id])
end
on your update action of the same controller, you don't have to change nothing, and you can put this code in your form:
<%= form_for #rfp do |f| %>
<%= f.fields_for : rfp_hors do |item| %>
<%= item.field_one :field %>
<%= item.field_two :field %>
<% end %>
<% end %>
in this way you can to receive the params as nested form in the same controller in the update action and you can show the params of this mode:
Parameters: {"rfp"=>{"rfp_hors_attributes"=>{"ecommerce_est_hours"=>"7", "rfp_id"=>"13", "designcomplexity_est_hours"=>"3", "browser_est_hours"=>"4", "framworks_est_hours"=>"5", "cms_est_hours"=>"6"}}, "utf8"=>"✓", "commit"=>"Create Rfp hor", "authenticity_token"=>"XXgQlufpBP2lvcde/EiFIx93aM5Ov47MNFqsCkLun2Y="}

multiple select

I am trying to create a form that allows to assign multiple projectmembers to a project.
(User and Project model being related through UserProject )
here is my view:
<div class="field">
<%= fields_for :projectmember do |u| %>
<%= u.label :projectmember %><br />
<%= select_tag :projectmember, options_for_select(User.all.collect {|u| [u.id, u.lastname]}, :projectmember),:multiple => true, :prompt => 'Select Person' %>
<% end %>
</div>
i have put the projectmember tag all over the place but i can't figure it out how to save this field projectmember into my db projects and user_projects !!??
my projects_controller :
def new
#project = Project.new
#user_project=UserProject.new
#user=User.all
#user_lastnames = User.all.collect do |u|
u.lastname
end
respond_to do |format|
format.html # new.html.erb
format.json { render json: #project }
end
end
and
def create
#project = Project.new(params[:project])
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: 'Project was successfully created.' }
format.json { render json: #project, status: :created, location: #project }
#user_project=UserProject.create(:project_id => #project.id, :user_id => #project.projectmember)
else
format.html { render action: "new" }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
After creating one instance, the command using the console : #project=Project.all gives :
Project id: 55, projectname: "fdfd", projectdescription: "fdfd", projectheader: "5", projectmember: nil, projecttypename: "dffd">]
Assuming your associations are something like this:
class Project < ActiveRecord::Base
has_many :project_users
has_many :users, :through=>:project_users
end
...for your project form, use the following helper with the "name" option (:name=>'project[user_ids][]') to pass the selected ids to your controller:
<%= select_tag :user_ids, options_for_select(User.all.collect {|u| [u.lastname, u.id]}),:multiple => true, :prompt => 'Select Person', :name=>'project[user_ids][]' %>
That will give you the selected ids in the params and then you'll have to hook up your controller actions to assign them. For example:
def create
#project = Project.new(params[:project])
users = User.find(params[:project][:user_ids]) rescue []
#project.users = users
if #project.save
...
else
...
end
end
def update
#project = Project.find(params[:id])
users = User.find(params[:project][:user_ids]) rescue []
#project.users = users
if #project.update_attributes(params[:project])
...
else
...
end
end
In order to get the selected items to re-select when you render the edit form, I'm assuming you'd have to add that as an argument to the options_for_select method. Not exactly sure about that. An alternative to doing all of the above would be to use checkboxes to select the users since the checked could be set for each assigned user when the form renders. Good luck.
my model was indeed like that :
class Project < ActiveRecord::Base
has_many :project_users
has_many :users, :through=>:project_users
attr_accessible :colourcode, :projectdescription, :user_id, :projectname, :projectheader, :projectmember, :projecttypename
end
i have needed to change in my view ( else Can't mass-assign protected attributes):
<%= select_tag :user_ids, options_for_select(User.all.collect {|u| [u.lastname, u.id]}),:multiple => true, :prompt => 'Select Person', :name=>'project[user_ids][]' %>
by
<%= select_tag :projectmember, options_for_select(User.all.collect {|u| [u.lastname, u.id]}),:multiple => true, :prompt => 'Select Person', :name=>'project[projectmember][]' %>
and in my controller:
def create
#project = Project.new(params[:project])
users = User.find(params[:project][:projectmember]) rescue []
#project.users = users
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: 'Project was successfully created.' }
format.json { render json: #project, status: :created, location: #project }
#user_project=UserProject.create(:project_id => #project.id, :user_id => #project.projectmember)
#user_project=UserProject.create(:project_id => #project.id, :user_id => #project.projectheader)
i got now after creation :
#p=Project.all
Project id: 69, projectname: "test", projectdescription: "blabla", colourcode: "blue", projectheader: "5", projectmember: "---\n- '5'\n- '6'\n", projecttypename: "caucasian">]
#up=UserProject.all
UserProject id: 86, project_id: 69, user_id: 5, created_at: "2012-06-07 13:04:51", updated_at: "2012-06-07 13:04:51">
UserProject id: 87, project_id: 69, user_id: 6, created_at: "2012-06-07 13:04:51", updated_at: "2012-06-07 13:04:51">,
which i am happy about :)
still need to :
delete automatically the project/user couple if the project is deleted
show on the screen the corresponding member names rather than an id number...

Resources