Rails: Method to check the database appointment is not taken - not saving - ruby-on-rails

I have a very beginners understanding of rails and ruby and I keep
getting stuck. If anyone could please point out my where I'm going wrong, that would be great! Or else, is there an easier way to validate the database before I allow an appointment? I don't want double bookings.
I am making an appointment booking app and I have a very basic design. I
have created an appointments scaffold with name:string phone:string
email:string numpeople:integer date:date timeslot:string.
In the view for creating a new appointment I have stated that appointment 1 is
9-11am, appointment 2 is 12-2pm, appointment 3 is 3-5pm and appointment
4 is 5 - 7pm. The user is asked to enter 1,2,3 or 4.
When the user clicks on "make appointment" I'm trying to interrupt the
appointments controller (create method) so that I can check if the date
&& timeslot are nil. if that is the case, the system should continue on
to create the appointment, if not then I want to redirect to somewhere
else. I have created a method called isValid? in the model (See below)
I think the method is correct as the system is getting as far as the
redirect. Tclass Appointment < ActiveRecord::Base
class Appointment < ActiveRecord::Base
def isValid?
taken = Appointment.where("date = ? && timeslot = ?", date, timeslot)
save unless taken
end
end
The problem is, it keeps redirecting to the page I told it to
go to if it's not saved(the homepage or root_path). (Also the
appointments are not saving).
appointments controller create method:
def create
valid = #appointment = Appointment.new(appointment_params).isValid?
respond_to do |format|
if valid
format.html { redirect_to new_appointment_path, notice: 'Appointment was
successfully created.' }
format.json { render :show, status: :created, location: #appointment }
else
format.html { redirect_to appointments_path, notice: 'That appointment
is not available, please choose again' } # this redirect works with no
notice
format.js { render json: #appointment.errors, status:
:unprocessable_entity }
end
end
end
Full appointments controller class: (In case I've missed something)
class AppointmentsController < ApplicationController
before_action :set_appointment, only: [:show, :edit, :update, :destroy]
def index
#appointments = Appointment.all
end
def show
end
def new
#appointment = Appointment.new
end
def edit
end
def create
valid = #appointment = Appointment.new(appointment_params).isValid?
respond_to do |format|
if valid
format.html { redirect_to new_appointment_path, notice: 'Appointment was
successfully created.' }
format.json { render :show, status: :created, location: #appointment }
else
format.html { redirect_to appointments_path, notice: 'That appointment
is not available, please choose again' } # this redirect works with no
notice
format.js { render json: #appointment.errors, status:
:unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #appointment.update(appointment_params)
format.html { redirect_to #appointment, notice: 'Appointment was
successfully updated.' }
format.json { render :show, status: :ok, location: #appointment }
else
format.html { render :edit }
format.json { render json: #appointment.errors, status:
:unprocessable_entity }
end
end
end
def destroy
#appointment.destroy
respond_to do |format|
format.html { redirect_to appointments_url, notice: 'Appointment was
successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_appointment
#appointment = Appointment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list
through.
def appointment_params
params.require(:appointment).permit(:name, :phone, :email, :numpeople,
:date, :timeslot)
end
end

I think your method should be something like:
class Appointment < ActiveRecord::Base
def isValid?
taken = Appointment.where("date = ? && timeslot = ?", date, timeslot)
save unless taken.present?
end
end
Let me know if that works.

Related

Multiple create of one model in single form

Hello I am building ROR Survey application for survey. I am having a problem of saving multiple objects into my database.My paramters after submission look all good but instead get an error of:
undefined methodpermit' for #Array:0x00007ff29d873010`
My parameters look like
Parameters: {
"utf8"=>"✓",
"authenticity_token"=>"vdUPSIU43ex1Wx3qZB4Xr6qNEaG0FbEyK2tkJ9OCcAtxK3jHe5lKVohS9JFOdpx/cISwIvzAKTRGw5zxUUS4QA==",
"survey_response"=>[
{"user_id"=>"1", "survey_question_id"=>"22", "answer"=>"Hello"},
{"user_id"=>"1", "survey_question_id"=>"23", "answer"=>"Hello"}],
"commit"=>"Create Survey response"
}
My survey_response_params methods is
def survey_response_params
params.require(:survey_response).permit(:answer, :survey_question_id, :user_id, :survey_answer_id)
end
My controller looks like :
class SurveyResponsesController < ApplicationController
def index
#survey_responses = SurveyResponse.all
end
def show
end
def new
#survey_response = SurveyResponse.new
#survey = Survey.find(1)
#survey_questions = #survey.survey_questions
end
def edit
#survey = Survey.find(1)
#survey_questions = #survey.survey_questions
end
def create
#survey_response = SurveyResponse.new(survey_response_params)
respond_to do |format|
if #survey_response.save
format.html { redirect_to #survey_response, notice: 'Survey response was successfully created.' }
format.json { render :show, status: :created, location: #survey_response }
else
format.html { render :new }
format.json { render json: #survey_response.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #survey_response.update(survey_response_params)
format.html { redirect_to #survey_response, notice: 'Survey response was successfully updated.' }
format.json { render :show, status: :ok, location: #survey_response }
else
format.html { render :edit }
format.json { render json: #survey_response.errors, status: :unprocessable_entity }
end
end
end
def destroy
#survey_response.destroy
respond_to do |format|
format.html { redirect_to survey_responses_url, notice: 'Survey response was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_survey_response
#survey_response = SurveyResponse.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def survey_response_params
params.permit(survey_response: [:answer, :survey_question_id, :user_id, :survey_answer_id])
end
end
Model
class SurveyResponse < ApplicationRecord
belongs_to :survey_question
belongs_to :user
end
You need to change your strong params, for array it looks like:
def survey_response_params
params.permit(survey_response: [:answer, :survey_question_id, :user_id, :survey_answer_id])
end
UPDATE:
I don't know anything about your models and controller, but I think it should be something like this in the controller
survey_response_params[:survey_response].each do |attrs|
SurveyResponse.new(attrs)
end

Ruby on Rails ActiveResource not saving resource model properly

ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux],
Rails 4.2.5
I have two projects. from 1st project i am getting data into second project through api.
User model in 1st project:
class User < ActiveRecord::Base
has_many :cars
end
Car model in 1st project:
class Car < ActiveRecord::Base
belongs_to :user
end
Car model(remote) in 2nd project:
class Car < ActiveResource::Base
self.site = 'https://myeasyb-vssram.c9users.io'
self.format = :json
end
Gpstablecontroller(2nd project):
class GpstablesController < ApplicationController
before_action :set_gpstable, only: [:show, :edit, :update, :destroy]
# GET /gpstables
# GET /gpstables.json
def index
#gpstables = Gpstable.all
end
# GET /gpstables/1
# GET /gpstables/1.json
def show
end
# GET /gpstables/new
def new
#gpstable = Gpstable.new
#gpstables = Gpstable.all
end
# GET /gpstables/1/edit
def edit
#gpstables = Gpstable.all
end
# POST /gpstables
# POST /gpstables.json
def create
#cars = Car.all
#gpstable = Gpstable.new(gpstable_params)
#cars.each do |car|
if #gpstable.car_id == car.id
#car = car
end
end
#car.update_attribute(:gpss, #gpstable.device_id)
respond_to do |format|
if #gpstable.save
format.html { redirect_to gpstables_url, notice: 'Gpstable was successfully created.' }
format.json { render :show, status: :created, location: #gpstable }
else
format.html { render :new }
format.json { render json: #gpstable.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /gpstables/1
# PATCH/PUT /gpstables/1.json
def update
respond_to do |format|
if #gpstable.update(gpstable_params)
Car.all.each do |car|
if #gpstable.car_id == car.id.to_json
#car = car
end
if #gpstable.device_id == car.gpss
car.gpss = 0
car.save!
end
end
#car.gpss = #gpstable.device_id
#car.save!
format.html { redirect_to #gpstable, notice: 'Gpstable was successfully updated.' }
format.json { render :show, status: :ok, location: #gpstable }
else
format.html { render :edit }
format.json { render json: #gpstable.errors, status: :unprocessable_entity }
end
end
end
# DELETE /gpstables/1
# DELETE /gpstables/1.json
def destroy
#cars.each do |car|
if #gpstable.device_id == car.gpss
car.gpss = 0
car.user_id = #gpstable.user_id
car.save
end
end
#gpstable.destroy
respond_to do |format|
format.html { redirect_to gpstables_url, notice: 'Gpstable was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_gpstable
#gpstable = Gpstable.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def gpstable_params
params.require(:gpstable).permit(:device_id, :car_id, :user_id)
end
end
when creating gpstable record i want to update Gpss attribute of car model(remote, calling through api).
it is updating gpss attribute.But it is changing all foriegnkeys including user_id attribute of car model to null.
using devise for users in 1st project.
The problem is i am giving user_id to current user_id in car_params. so i was unable to edit this through resource model. so i changed this to create action.
In my first app i have car controller:
def car_params
params.require(:car).permit(:name, :model, :colour, :ac, :gpss, :wifi, :luggage, :cfare, :card, :crfare, :no, :nos, :user_id, {carpicss: []} ).**merge(user: :current_user)**
end
i removed .merge(user: :current_user) from above code.
and added this in create action
def create
#car = Car.new(car_params)
#car.card=" #{#car.name} : #{#car.no}"
#car.user_id=current_user.id #added here to save current user_id
respond_to do |format|
if #car.save
format.html { redirect_to cars_path, notice: 'Car was successfully created.' }
format.json { render :show, status: :created, location: cars_path }
else
format.html { render :new }
format.json { render json: #car.errors, status: :unprocessable_entity }
end
#car.reload
end
end

rails redirect in controller for a loop

I have create method like this in rails controller:
def create
#sale = Sale.new(sale_params)
#sale.user_id = current_user.id
#sale.total = #sale.total_all
params[:sale][:items_attributes].values.each do |p|
#product = Product.find(p['product_id'])
if #product.quantity.to_i - p['quantity'].to_i <= 0
flash.now[:notice] = "Quantity is higher then stock"
end
end
respond_to do |format|
if #sale.save
format.html { redirect_to #sale, notice: 'Sale was successfully created.' }
format.json { render :show, status: :created, location: #sale }
else
format.html { render :new }
format.json { render json: #sale.errors, status: :unprocessable_entity }
end
end
end
if #product.quantity.to_i - p['quantity'].to_i <= 0
flash.now[:notice] = "Quantity is higher then stock"
end
this condition fails it means the controller redirected to create page itself otherwise it needs to redirect to index page. If I puts render :new in loop rails says error. How to do this?
You can move it to the model as Harsh suggested. You'd do it something like this. Then you can get rid of the loop.
class Sale < ActiveRecord::Base
has_many :items
# Also make sure you validate children
validates_associated :items
validate :items_in_stock
def items_in_stock
items.each do |i|
if i.quantity > i.product.quantity
i.errors.add(:quantity) = "is not currently available"
end
end
end
end

Merit doesn't add points to user after create action

I've used this instructions for simply add score when a user creates a "solucion" (which is a kind of "answer" to a micropost). I have added the has_merit line to user.rb (user model).
I want to display the user points earned for that action at the show view.
show.html.erb (for solucion):
<h2><span class="red"><%= current_user.points %></span><br>Points</br></h2>
It displays 0 points...
point_rules.rb:
module Merit
class PointRules
include Merit::PointRulesMethods
def initialize
score 5, on: 'solucions#create'
end
end
end
When I create a solucion with the current_user (already saving the user_id index and identifier to solucion), This is what my rails server output shows...
Direct link to github gist:
https://gist.github.com/roadev/7b34fd67ab93c979fa48
Embed:
<script src="https://gist.github.com/roadev/7b34fd67ab93c979fa48.js"></script>
EDIT:
solucions_micropost.rb
class SolucionsController < ApplicationController
before_action :set_solucion, only: [:show, :edit, :update, :destroy]
def index
#solucions = Solucion.all
end
def show
end
def new
#solucion = current_user.solucions.build
end
def edit
end
def create
#solucion = current_user.solucions.build(solucion_params)
respond_to do |format|
if #solucion.save
format.html { redirect_to #solucion, notice: 'Solucion was successfully created.' }
format.json { render action: 'show', status: :created, location: #solucion }
else
format.html { render action: 'new' }
format.json { render json: #solucion.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #solucion.update(solucion_params)
format.html { redirect_to #solucion, notice: 'Solucion was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #solucion.errors, status: :unprocessable_entity }
end
end
end
def destroy
#solucion.destroy
respond_to do |format|
format.html { redirect_to solucions_url }
format.json { head :no_content }
end
end
private
def set_solucion
#solucion = Solucion.find(params[:id])
end
def current_micropost
#solucion = microposts.find_by(id: params[:id])
end
def solucion_params
params.require(:solucion).permit(:solucion, :image, :micropost_id)
end
end
user.rb:
class User < ActiveRecord::Base
has_many :dreams
has_many :microposts
has_many :solucions
has_merit
end
I had a problem with a migration when I installed the merit gem.

how do I write create method in the controller for a submission form that uses a join table?

I'm trying to create a form that allow called submits. I've got all the appropriate MVC created. I've then created a model called questions that works and am using active admin to allow admin users to add new questions to the form as they see fit. When I test submitting the form I get this error
undefined method `each' for nil:NilClass
#submit = Submit.new(submit_params)
#submit.save
params[:submit][:question_ids].each do |question_id|
#question = Question.find(question_id)
#submit.questions << #question
end
Here's my submits controller:
class SubmitsController < ApplicationController
before_action :set_submit, only: [:show, :edit, :update, :destroy]
def index
#submits = Submit.all
end
def show
end
def new
#submit = Submit.new
#questions = Question.all
end
def edit
end
def create
#submit = Submit.new(submit_params)
#submit.save
params[:submit][:question_ids].each do |question_id|
#question = Question.find(question_id)
#submit.questions << #question
end
respond_to do |format|
if #submit.save
format.html { redirect_to #submit, notice: 'Application was successfully created.' }
format.json { render :show, status: :created, location: #submit }
else
format.html { render :new }
format.json { render json: #submit.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #submit.update(submit_params)
format.html { redirect_to #submit, notice: 'Application was successfully updated.' }
format.json { render :show, status: :ok, location: #submit }
else
format.html { render :edit }
format.json { render json: #submit.errors, status: :unprocessable_entity }
end
end
end
def destroy
#submit.destroy
respond_to do |format|
format.html { redirect_to submits_url, notice: 'Submit was successfully destroyed.' }
format.json { head :no_content }
end
end
Here's my Submit and Question model:
Submit:
class Submit < ActiveRecord::Base
has_and_belongs_to_many :questions
belongs_to :user
end
Question:
class Question < ActiveRecord::Base
has_and_belongs_to_many :submits
end
I'm sure it's some kind of syntax error in my controller but I don't know what. Still pretty new to using join tables. Any help/explanation would be very appreciated.
Thanks!
You don't need this
params[:submit][:question_ids].each do |question_id|
#question = Question.find(question_id)
#submit.questions << #question
end
I don't see your submit params but if you add question ids to the permitted parameters then rails will build the entry in the join table on it's own.
def submit_params
params.require(:submit).permit(:user_id, question_ids: [])
end

Resources