Rails: How not to save value with using time_select - ruby-on-rails

I'm trying to add time_select with include_blank. I'm doing this:
<%= f.time_select :start_at, include_blank: true, ampm: true %><br>
What I'd like to do is to delete value (save nil?) if blank is selected in view.
Although I tried the following posts, it didn't work for me.
time_select blank field saves a default time when form is submitted
Optional time_select with allow_blank defaults to 00:00
1) When I try as below, no error is appeared, but 00:00:00 is saved.
controller
def update
#event = Event.find(params[:id])
if event_params["start_at(4i)"].blank? or event_params["start_at(5i)"].blank?
#event.start_at = nil
end
if #event.update(event_params)
flash[:success] = "event updated!"
redirect_to root_url
else
render 'edit'
end
end
2) When I try as below (change if clause), no error is appeared, but 00:00:00 is saved.
controller
def update
#event = Event.find(params[:id])
if params[:id]["start_at(4i)"].blank? or params[:id]["start_at(5i)"].blank?
#event.start_at = nil
end
if #event.update(event_params)
flash[:success] = "event updated!"
redirect_to root_url
else
render 'edit'
end
end
3) When I try as below (add before_action), no error is appeared, but 00:00:00 is saved.
controller
before_action :blank_time, only: [:update]
def update
#event = Event.find(params[:id])
if #event.update(event_params)
flash[:success] = "event updated!"
redirect_to root_url
else
render 'edit'
end
end
private
def blank_time
if params[:id]["start_at(4i)"].blank? or params[:id]["start_at(5i)"].blank?
params[:id]['start_at(1i)'] = ""
params[:id]["start_at(2i)"] = ""
params[:id]["start_at(3i)"] = ""
params[:id]["start_at(4i)"] = ""
params[:id]["start_at(5i)"] = ""
end
end
4) When I try as below (use nil instead of ""), error is appeared.
error
IndexError (string not matched):
app/controllers/events_controller.rb:106:in `[]='
app/controllers/events_controller.rb:106:in `blank_time'
controller
before_action :blank_time, only: [:update]
def update
#event = Event.find(params[:id])
if #event.update(event_params)
flash[:success] = "event updated!"
redirect_to root_url
else
render 'edit'
end
end
private
def blank_time
if params[:id]["start_at(4i)"].blank? or params[:id]["start_at(5i)"].blank?
params[:id]['start_at(1i)'] = nil
params[:id]["start_at(2i)"] = nil
params[:id]["start_at(3i)"] = nil
params[:id]["start_at(4i)"] = nil
params[:id]["start_at(5i)"] = nil
end
end
It would be appreciated if you could give me any advice.
UPDATE
Although I change the edit in events_controller.rb as below, the error ActiveModel::MissingAttributeError (can't write unknown attribute 'start_at(4i)'): is displayed.
def edit
#room = Room.find(params[:room_id])
#event = #room.events.find(params[:id])
#event['start_at(4i)'] = #event.start_at.split(':')[0] #the error occur here
#event['start_at(5i)'] = #event.start_at.split(':')[1]
end

My idea works like this:
Migration:
class CreateTests < ActiveRecord::Migration[5.0]
def change
create_table :tests do |t|
t.string :time
t.timestamps
end
end
end
Form:
<%= form_for(test) do |f| %>
<% if test.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(test.errors.count, "error") %> prohibited this test from being saved:</h2>
<ul>
<% test.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :time %>
<%= f.time_select :time, include_blank: true, ampm: false %><br>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Controller:
This will save : when value send are null where you can use conditional to check if parameters are null or and set value of time. //It's consuming much time and I skipped for you to complete.
def create
#test = Test.new(test_params)
#time = (params[:test]['time(4i)']).to_s
#time_ampm = (params[:test]['time(5i)']).to_s
#test.time = #time+":"+ #time_ampm
respond_to do |format|
if #test.save
format.html { redirect_to #test, notice: 'Test was successfully created.' }
format.json { render :show, status: :created, location: #test }
else
format.html { render :new }
format.json { render json: #test.errors, status: :unprocessable_entity }
end
end
end
For updating
def edit
#test = Test.find(params[:id])
#test['time(4i)'] = #test.time.split(':')[0]
#test['time(5i)'] = #test.time.split(':')[1]
end
def update
#test = Test.find(params[:id])
#time = (params[:test]['time(4i)']).to_s
#time_ampm = (params[:test]['time(5i)']).to_s
#test.time = #time+":"+ #time_ampm
#test.update(test_params)
end

Assigning #event.starts_at to nil does nothing as the attributes in #event_params is used when calling #update, overwriting your initial assignment.
Overwriting the starts_at attribute in your params should work instead.
def update
#event = Event.find(params[:id])
if event_params["start_at(4i)"].blank? or event_params["start_at(5i)"].blank?
event_params = event_params.reject { |k, v| k.starts_with? 'starts_at' }
.merge(starts_at: nil)
end
if #event.update(event_params)
flash[:success] = "event updated!"
redirect_to root_url
else
render 'edit'
end
end
The following line finds and remove the parameters for starts_at(1i) to starts_at(5i), then sets the whole starts_at attribute to be nil:
event_params.reject { |k, v| k.starts_with? 'starts_at' }.merge(starts_at: nil)

Related

nil when trying to display data in rails app

I get this error when trying to show <%= #schedule.title %>, but when I do the same with <%= #lesson.title %> it is working fine for #lesson.
![undefined method `title' for nil:NilClass
]1
The flow is like this.
- A user signs up and creates a clinic, the clinic belongs to the user.
- A clinic has many practitioners and they belongs to the clinic.
- A practitioner has many lessons and schedules, and they belongs to the practitioner.
When I'm on the lesson show page, there is a link to a booking page. It's on this booking page that the error occours.
I know it's saying nil, but both lessons and schedules have been created for that specific practitioner.
Anybody knows why this is happening? I don't understand why I can access #lesson but not #schedule. Any help would be much appreciated.
routes.rb
resources :clinics do
resources :practitioners do
resources :lessons, :lesson_payments, :schedules do
resources :bookings do
end
end
end
end
schedules_controller.rb
class SchedulesController < ApplicationController
before_action :set_schedule, only: [:show, :edit, :update, :destroy]
# GET /schedules
# GET /schedules.json
def index
#schedules = Schedule.all
end
# GET /schedules/1
# GET /schedules/1.json
def show
end
# GET /schedules/new
def new
#schedule = Schedule.new
end
# GET /schedules/1/edit
def edit
end
# POST /schedules
# POST /schedules.json
def create
#schedule = Schedule.new(schedule_params)
respond_to do |format|
if #schedule.save
format.html { redirect_to clinic_practitioner_schedule_path(id: #schedule.id), notice: 'Schedule was successfully created.' }
format.json { render :show, status: :created, location: #schedule }
else
format.html { render :new }
format.json { render json: #schedule.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /schedules/1
# PATCH/PUT /schedules/1.json
def update
respond_to do |format|
if #schedule.update(schedule_params)
format.html { redirect_to clinic_practitioner_schedule_path(#schedule), notice: 'Schedule was successfully updated.' }
format.json { render :show, status: :ok, location: #schedule }
else
format.html { render :edit }
format.json { render json: #schedule.errors, status: :unprocessable_entity }
end
end
end
# DELETE /schedules/1
# DELETE /schedules/1.json
def destroy
#schedule.destroy
respond_to do |format|
format.html { redirect_to clinic_practitioner_schedules_url, notice: 'Schedule was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_schedule
#schedule = Schedule.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def schedule_params
params.require(:schedule).permit(:title, :start, :end, :practitioner_id, :account_id)
end
end
bookings_controller.rb
class BookingsController < ApplicationController
before_action :set_lesson, only: [:new]
def new
#account = Account.new
#user = User.new
#patient = Patient.new
#booking = Booking.new
#lesson_payment = LessonPayment.new
#schedule = Schedule.find_by_id(params[:id])
end
def create
create_patient_charge
create_patient_account
#user = User.new(user_params)
#user.account_id = #account.id
respond_to do |format|
if #user.save
create_patient_profile
create_patient_booking
create_patient_lesson_payment
auto_login(#user)
UserMailer.new_signup_booking_admin(#user, #booking).deliver_later
UserMailer.new_signup_booking_client(#user, #booking).deliver_later
format.html { redirect_to dashboard_url, notice: 'Your account was successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { redirect_back fallback_location: root_path, alert: 'An error occurred while sending this request.' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
private
def set_lesson
#lesson = Lesson.find(params[:lesson_id])
end
def user_params
params.require(:user).permit(:email, :password, :time_zone)
end
def create_patient_account
#account = Account.new()
#account.status = 'active'
#account.account = 'prefix-' + SecureRandom.hex(4)
#account.account_type = 'client'
#account.save
end
def create_patient_profile
#patient = Patient.new()
#patient.firstname = params[:user][:patient][:patient_first_name]
#patient.lastname = params[:user][:patient][:patient_last_name]
#patient.phone = params[:user][:patient][:patient_phone]
#patient.user_id = #user.id
#patient.account_id = #user.account_id
#patient.save
end
def create_patient_booking
#lesson = Lesson.find(params[:user][:booking][:lesson_id])
#booking = Booking.new()
#booking.lesson_id = params[:user][:booking][:lesson_id]
#booking.schedule_id = params[:user][:booking][:schedule_id]
#booking.patient_id = #patient.id
#booking.account_id = #user.account_id
#booking.title = #lesson.title
#booking.cost = #lesson.cost
#booking.status = 'Booked'
#booking.save
#schedule = Schedule.find(params[:user][:booking][:schedule_id])
#booking.practitioner_id = #schedule.practitioner_id
#booking.start = #schedule.start
#booking.refunded = 0
#booking.save
#schedule.title = 'Booked'
#schedule.save
end
def create_patient_lesson_payment
#lesson_payment = LessonPayment.new()
#lesson_payment.status = 'Paid'
#lesson_payment.date = Date.today
#lesson_payment.cost = #lesson.cost
#lesson_payment.service = #lesson.title
#lesson_payment.booking_id = #booking.id
#lesson_payment.account_id = #user.account_id
#lesson_payment.save
end
end
This is where I link to the booking page
show.html.erb
<p id="notice"><%= notice %></p>
<%= link_to new_clinic_practitioner_lesson_booking_path(:lesson_id => #lesson.id), class: "course-btn" do %><i class="fa fa-calendar-plus-o"></i> Book This Lesson<% end %>
<p>
<strong>Image:</strong>
<%= #lesson.image %>
</p>
<p>
<strong>Title:</strong>
<%= #lesson.title %>
</p>
<p>
<strong>Duration:</strong>
<%= #lesson.duration %>
</p>
<p>
<strong>Cost:</strong>
<%= #lesson.cost %>
</p>
<p>
<strong>Category:</strong>
<%= #lesson.category %>
</p>
<p>
<strong>Language:</strong>
<%= #lesson.language %>
</p>
<p>
<strong>Level:</strong>
<%= #lesson.level %>
</p>
<p>
<strong>Description:</strong>
<%= #lesson.description %>
</p>
<p>
<strong>Practitioner:</strong>
<%= #lesson.practitioner_id %>
</p>
<p>
<strong>Account:</strong>
<%= #lesson.account_id %>
</p>
<%= link_to 'Edit', edit_clinic_practitioner_lesson_path(#lesson) %> |
<%= link_to 'Back', clinic_practitioner_lessons_path %>
new.html.erb
<h1>New Booking</h1>
<%= render 'form', booking: #booking %>
<%= link_to 'Back', clinic_practitioner_lesson_bookings_path %>
_form.html.erb
<table class="table table-bordered">
<thead>
<tr>
<th>Slots In The User's Time Zone</th>
<th>Price</th>
<th>Service Provider</th>
<th>Booking Button</th>
</tr>
</thead>
<tbody>
<tr>
<td><%= #lesson.title %></td>
<td><%= #schedule.title %></td>
</tr>
</tbody>
</table>
I am noticing that in you are initializing #schedule like this in your bookings_controller new method:
#schedule = Schedule.find_by_id(params[:id])
But, you don't have any params[:id] in your parameters that are:
{'clinic_id'=>'50','practitioner_id'=>'27','lesson_id'=>'15'}
This is why your #schedule is nil
Assuming, there is a has_many association between practitioner and schedule, and you want to display the title of first schedule of the practitioner, you can do it it like this:
#schedule = Schedule.find_by_practitioner_id(params[:practitioner_id])

Rails 4 - How to insert an additional row when you submit a form?

I am building a simple application with Ruby on Rails. I have three tables in my database: users, events and invites.
Any user can create an invite via form, where he/she selects the user, that he/she wants to invite, and the event, that he/she wants to invite that person to.
Now, I would like to make it so that everytime somebody creates an invite, he/she also invites another user called "Intruder".
So, everytime the invite form is submitted, two rows should be inserted into the database:
First with the data that the user picked
Second where user_id matches the id of the "Intruder", while event_id is the same as in the first row.
Here's my invites controller:
def new
#invite = Invite.new
#users = User.where.not(:id => current_user).order(full_name: :ASC)
#user = User.new
#events = Event.where(:user_id => current_user).order(startsAt: :ASC)
#event = Event.new
end
def create
#users = User.where.not(:id => current_user).order(full_name: :ASC)
#user = User.new
#events = Event.where(:user_id => current_user).order(startsAt: :ASC)
#event = Event.new
#invite = Invite.new(invite_params)
respond_to do |format|
if #invite.save
format.html { redirect_to events_path, notice: 'Invite was successfully created.' }
format.json { render :show, status: :created, location: #invite }
else
format.html { render :new }
format.json { render json: #invite.errors, status: :unprocessable_entity }
end
end
end
def invite_params
params.require(:invite).permit(:attending, :user_id, :event_id)
end
Here's my form for creating a new invite:
<%= form_for(#invite) do |f| %>
<% if #invite.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#invite.errors.count, "error") %> prohibited this invite from being saved:</h2>
<ul>
<% #invite.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :user_id, 'Name' %>
<%= f.select :user_id, options_for_select(#users.collect { | user | [user.full_name, user.id] }, #user.id), {}, class: 'inv-select' %>
</div>
<div class="field">
<%= f.label :event_id %>
<%= f.select :event_id, options_for_select(#events.collect { | event | [event.title, event.id] }, #event.id), {}, class: 'inv-select' %>
</div>
<div class="actions">
<%= f.submit 'Invite' %>
</div>
<% end %>
No need to add the Intruder part to your views since it's just a backend implementation detail if I understood your question correctly.
So, you can extract the Intruder insertion part to a method and call it right after inserting the new invitation for the other user:
def create
#users = User.where.not(:id => current_user).order(full_name: :ASC)
#user = User.new
#events = Event.where(:user_id => current_user).order(startsAt: :ASC)
#event = Event.new
#invite = Invite.new(invite_params)
respond_to do |format|
if #invite.save && invite_intruder
format.html { redirect_to events_path, notice: 'Invite was successfully created.' }
format.json { render :show, status: :created, location: #invite }
else
format.html { render :new }
format.json { render json: #invite.errors, status: :unprocessable_entity }
end
end
end
protected
def invite_intruder
intruder = User.find_by(full_name: "Intruder")
Invite.new(event_id: invite_params[:event_id], user_id: intruder.id).save
end
You'll probably want to add some custom error handling in case the invitation to Intruder fails, but it's not clear if you want this second invitation to be transparent to the user or hidden.
You can add an auxiliary attribute to the invite model, to hold the intruder:
attr_accesor :intruder_id
You can add the intruder in the form:
<div class="field">
<%= f.label :intruder_id, 'Intruder' %>
<%= f.select :intruder_id, options_for_select(#users.collect { | user | [user.full_name, user.id] }), {}, class: 'inv-select' %>
</div>
Add the intruder_id to params
def invite_params
params.require(:invite).permit(:attending, :user_id, :intruder_id, :event_id)
end
You don't need user and event in the new
def new
#invite = Invite.new
#users = User.where.not(:id => current_user).order(full_name: :ASC)
#events = Event.where(:user_id => current_user.id).order(startsAt: :ASC)
end
Create two invites:
def create
#users = User.where.not(:id => current_user).order(full_name: :ASC)
#events = Event.where(:user_id => current_user).order(startsAt: :ASC)
#invite = Invite.new(invite_params)
#intruder_invite Invite.new(invite_params)
#intruder_invite.user_id = invite_params[:intruder_id] # Change the invitee
respond_to do |format|
if #invite.save
if #intruder_invite.save
format.html { redirect_to events_path, notice: 'Main and intruder invites were successfully created.' }
format.json { render :show, status: :created, location: #invite }
else
format.html { redirect_to events_path, notice: 'Main invite was created, but an error prevented the intruder invite to be created.' }
format.json { render :show, status: :created, location: #invite }
end
else
format.html { render :new }
format.json { render json: #invite.errors, status: :unprocessable_entity }
end
end
end
This would be the function of the callbacks mechanism in rails, probably the before_create callback as it won't require an additional save.
class Invite < ApplicationRecord
before_create :add_intruder
protected
def add_intruder
self.users << User.find_by full_name: "Intruder"
end
end
Although TBH a better way would be to handle this in SQL via a trigger.

Rails: model validations and errors not appearing

I'm creating multiple objects from a single form:
def new
#opening_hour = []
7.times do
#opening_hour << OpeningHour.new
end
render :template => "stores/opening_hours/new"
end
def create
params["opening_hour = "].each do |hour|
if hour["day"] != "" || hour["closes"] != "" || hour["opens"] != ""
#res = OpeningHour.new(opening_hour_params(hour))
puts #res.errors unless #res.save
redirect_to(store_items_index_path)
return
end
end
end
and the form looks like this:
<%= form_tag store_opening_hours_create_path do %>
<% #opening_hour.each do |hour| %>
<%= fields_for 'opening_hour = []', hour do |p|%>
<% if #res.errors.any? %>
<div class="centerList">
<div id="error_explanation">
<h2><%= pluralize(#res.errors.count, "error") %> <%= t 'store_edit_account_errors' %></h2>
<% #res.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</div>
</div>
<% end %>
But after I click on submit... I get an error: undefined method 'errors' for nil:NilClass at this line <% if #res.errors.any? %>. If I delete the error part from the form then everything works fine and the all 7 objects get created. From my understanding this is happening because the value #res is nil... but not really sure how to make this work... any ideas??
Update 1
def new
#opening_hour = []
7.times do
#opening_hour << OpeningHour.new
end
render :template => "stores/opening_hours/new"
end
def create
params["opening_hour = "].each do |hour|
if hour["day"] != "" || hour["closes"] != "" || hour["opens"] != ""
#res = OpeningHour.new(opening_hour_params(hour))
if #res.success
format.html { redirect_to #res, notice: 'Hours were successfully created.' }
format.json { render :show, status: :ok, location: #res }
else
format.html { render :'stores/opening_hours/edit' }
format.json { render json: #res.errors, status: :unprocessable_entity }
end
end
end
end
Try instantiating it at the top of the create action. Probably it's not getting set as you think it is.
def create
#res = OpeningHour.new
# ...
end
You should also have to do something similar in the new action, #res is also not set there.
If you redirect, you trigger a new request where everything that happens before in memory is not persisted.
This is the reason why:
on success we redirect: everything went fine
on error, we render the form directly so it has the object with errors to display

Ruby: If last variable was saved more than 3 hours ago

I have a ruby form to submit reports for an exercise on my app. An exercise has_many reports. I want to create an if statement that makes this form only appear if the last report from that exercise was saved more than 3 hours ago.
So far I have:
But this is creating a NoMethodError saying undefined method 'report' for #<Exercise:0x007f9c892f48b0>.
It's being displayed on my workouts#show page (a workout has_many exercises, in case it helps), so I believe this is the reigning controller:
class WorkoutsController < ApplicationController
def index
#workouts = Workout.all
end
def show
#workout = Workout.find(params[:id])
#exercise = Exercise.new
#report = Report.new
end
def new
#workout = Workout.new
#workout.user_id = current_user
end
def create
#workout = Workout.new(workout_params)
#workout.user = current_user
if #workout.save
flash[:notice] = "Workout was saved successfully."
redirect_to #workout
else
flash.now[:alert] = "Error creating workout. Please try again."
render :new
end
end
def edit
#workout = Workout.find(params[:id])
end
def update
#workout = Workout.find(params[:id])
#workout.name = params[:workout][:name]
#workout.workout_type = params[:workout][:workout_type]
#workout.teaser = params[:workout][:teaser]
#workout.description = params[:workout][:description]
#workout.video = params[:workout][:video]
#workout.difficulty = params[:workout][:difficulty]
#workout.trainer = params[:workout][:trainer]
#workout.user_id = params[:workout][:user_id]
if #workout.save
flash[:notice] = "Workout was updated successfully."
redirect_to #workout
else
flash.now[:alert] = "Error saving workout. Please try again."
render :edit
end
end
def destroy
#workout = Workout.find(params[:id])
if #workout.destroy
flash[:notice] = "\"#{#workout.name}\" was deleted successfully."
redirect_to action: :index
else
flash.now[:alert] = "There was an error deleting the workout."
render :show
end
end
private
def workout_params
params.require(:workout).permit(:name, :workout_type, :teaser, :description, :video, :difficulty, :trainer, :user_id)
end
end
Any ideas where I'm going wrong?
ADDITIONAL INFORMATION:
This bit is technically on my workouts#show page:
<% if #workout.exercises.count == 0 %>
<p>Looks like you get a freebie for this one! No score report today. Rest up and drink some water. It ain't always that easy...</p>
<% else %>
<% #workout.exercises.each do |exercise| %>
<%= render 'reports/form', report: #report, exercise: exercise %>
<% if current_user.admin? %>
<div class="text-center"><%= link_to "Delete #{exercise.name}", [exercise], method: :delete, data: { confirm: 'Are you sure?' } %></div>
<% end %>
<hr>
<% end %>
But here is the partial it renders, where the code in question actually lies:
<% if exercise.report.last != nil && exercise.report.last.created_at < ( DateTime.now - (3/24.0)) %>
<%= form_for report,
:url => { :controller => "reports",
:action => :create,
:exercise_id => exercise.id } do |f| %>
<div class="row">
...
It seems you calling singularized report instead of reports.
if exercise.report.last
If reports relates to exercise as has_many you need to call it with exercise.reports.last
Also, you mentioned results in your question, but calling reports in your view.
An exercise has_many results.
...
exercise.report.last
Please be sure you calling appropriate pluralize method reports or results

Why no error with unassigned variable?

I have a pupils model and a groups model. When adding a new pupil I have a collection_select box with :multiple=> true so that the pupil can be put into several groups.
<div class="field">
<%= f.label "All Groups" %><br />
<%= collection_select(:groups, :id, #all_groups,
:id, :name, {},
{:multiple => true}) %>
</div>
I have an edit pupil form that when loaded selects the groups the pupil was previously assigned so that they can be changed if needs be so has the extra bit in {} in the collection select options;
<div class="field">
<%= f.label "All Groups" %><br />
<%= collection_select(:groups, :id, #all_groups,
:id, :name, {selected: #previous_selection},
{:multiple => true}) %>
</div>
the #previous_selection is set in the pupils_controller;
#previous_selection = Array.new
#pupil.groups.each do |pg|
#previous_selection.push(pg.id)
end
This is in the def edit block so only setup for the edit page.
Here is the PupilsController;
class PupilsController < ApplicationController
before_action :set_pupil, only: [:show, :edit, :update, :destroy]
def index
#pupils = Pupil.all
end
def show
#pupil_groups = #pupil.groups
end
def new
#pupil = Pupil.new
#all_groups = set_pupil_list
end
def edit
#all_groups = set_pupil_list
#previous_selection = Array.new
#pupil.groups.each do |pg|
#previous_selection.push(pg.id)
end
end
def create
#pupil = Pupil.new(pupil_params)
clean_select_multiple_params
logger.debug "The groups parameter contains: #{params[:groups][:id]}"
selected_groups = Group.find(params[:groups][:id])
#pupil.groups = selected_groups
respond_to do |format|
if #pupil.save
format.html { redirect_to #pupil, notice: 'Pupil was successfully created.' }
format.json { render action: 'show', status: :created, location: #pupil }
else
format.html { render action: 'new' }
format.json { render json: #pupil.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #pupil.update(pupil_params)
clean_select_multiple_params
selected_groups = Group.find(params[:groups][:id])
#pupil.groups = selected_groups
format.html { redirect_to #pupil, notice: 'Pupil was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #pupil.errors, status: :unprocessable_entity }
end
end
end
def destroy
#pupil.destroy
respond_to do |format|
format.html { redirect_to pupils_url }
format.json { head :no_content }
end
end
def full_name
#fn = #pupil.given_name
#sn = #pupil.surname
#full_name = #fn + #sn
end
private
def set_pupil
#pupil = Pupil.find(params[:id])
end
def set_pupil_list
Group.all
end
def clean_select_multiple_params hash = params
hash.each do |k, v|
case v
when Array then v.reject!(&:blank?)
when Hash then clean_select_multiple_params(v)
end
end
end
def pupil_params
params.require(:pupil).permit(:given_name, :surname, :date_of_birth, :gender, :ethnicity)
end
end
When the new pupil page is requested the _form.html.erb file is used that has the {selected: #previous_selection} argument in it that has not been set up by def new in the pupils_controller but there is not a error message about #previous_selection not being initialized.
I would expect an error but am not getting one but do not understand why. Could someone please explain? I am new to programming in general so sorry if I am using the wrong terminolog.
Thank you
Leon
#previous_selection variable is nil, and hence in the view none of collection items will be selected. It is not necessary to initialize a variable to nil, rails does that.

Resources