unable to do validations in rails - ruby-on-rails

I have a contact us page
class ContactPagesController < ApplicationController
def new
#contact_page = ContactPage.new
end
def create
#contact_page = ContactPage.new(contact_page_params)
if #contact_page.save
flash[:notice]="details saved successfully"
redirect_to contact_pages_path
else
flash[:notice]="details not saved"
redirect_to contact_pages_path
end
# if #contact_page.errors.any?
# flash[:notice]="there are errors"
# end
end
private
def contact_page_params
params.require(:contact_page).permit( :first_name, :last_name, :email, :phone, :do_you_have_land, :moving_time_frame, :financing, :to$
end
end
and my model
class ContactPage < ApplicationRecord
validates :email, presence: true
end
and the view
new.html.erb
<%= form_for #contact_page, :html => { :class => 'form-horizontal', multipart: true } do |f| %>
<% if #contact_page.errors.any? %>
<div id="error_explanation">
<h3>
<%= pluralize(#contact_page.errors.count, "error") %>
prohibited this employee from being saved:
</h3>
<ul>
<% #contact_page.errors.full_messages.each do |message| %>
<li>
<%= message %>
</li>
<% end %>
</ul>
</div>
<% end %>
<div class="control-group">
<%= f.label :First_Name, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :first_name, :class => 'text_field' %>
</div>
</div>
<div class="control-group">
<%= f.label :Email, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :email, :class => 'text_field' %>
</div>
</div>
<div class="control-group">
<%= f.label :How_can_we_assist_you, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :assist_you, :class => 'text_field' %>
</div>
</div>
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
</div>
<% end %>
If all the fields are filled the data is being saved into the database.If email is left blank data is also not being saved inside the database(due to validation), but the error message is also not rendering . The #contact_page.errors.any? inside the view page is being ignored for some reason.I am expecting an error "email can't be blank" on the top of the form.
why the save action is not triggering the validation errors?
my routes for contact page
get 'contact_pages' => 'contact_pages#new', :as => 'contact_pages'
post 'contact_pages' => 'contact_pages#create'
Need help in what I have gone wrong.Any help is highly appreciated.Thanks in advance.

class SaveController < ApplicationController
def new
#contact_page = ContactPage.new
end
def create
if
#contact_page.save
flash[:notice]="Successfuly stored"
redirect_to contact_pages_path
else
flash[:notice]="please check your inputs"
render :new
end
end
end
In View: -
<% if notice %>
<div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
<%= notice %>
</div>
<% end %>

you should user render on error not redirect
def create
#contact_page = ContactPage.new(contact_page_params)
if
#contact_page.save
flash[:notice]="details saved successfully"
redirect_to contact_pages_path
else
flash[:notice]="details not saved"
render :new
end
end

Related

Nested form validation in Rails

I have the following code:
<%= form_with(model: [#lawsuit, #lawsuit.suits.build]) do |f| %>
<fieldset>
<legend>New Suit</legend>
</fieldset>
<br />
<div class="form-group">
<%= f.label :claim %>
<%= f.text_field :claim, class: 'form-control', placeholder: 'Name' %>
</div>
<div class="form-group">
<%= f.label :sentence %>
<%= f.text_area :sentence, class: 'form-control', placeholder: 'Sentence' %>
</div>
<div class="form-group">
<%= f.label :result %>
<%= f.select(:result, [['Not Favorable', false], ['Favorable', true]], {}, {class: 'form-control'}) %>
</div>
<%= button_tag type: 'submit', class: "btn btn-primary float-right" do %>
<i class="fa fa-plus" aria-hidden="true"></i>
Create
<% end %>
<% end %>
How can I show the list of errors of the suit (which is a nested attribute of #lawsuit) and show it's errors on the screen ? I have already done the validations on the model. The model is like that:
class Suit < ApplicationRecord
belongs_to :lawsuit
validates_presence_of :claim, :sentence
end
My controllers are like below.
The process start in lawsuit controller. There I build the #suit (which is used in the form).
Suit controller:
class SuitsController < ApplicationController
before_action :set_suit, only: [:show]
def new
end
def create
Rails.logger.info "=====================SUIT CREATION"
#lawsuit = Lawsuit.find(params[:lawsuit_id])
#suit = #lawsuit.suits.build(suit_params)
Rails.logger.info "AISHA #{#suit.errors.any?}"
# #suit = #lawsuit.suits.new(suit_params)
if #suit.save
flash[:notice] = "Suit created successfully"
redirect_to lawsuit_path(#lawsuit)
else
Rails.logger.info "AISHA #{#suit.valid?}"
flash[:alert] = "Something went wrong"
redirect_to lawsuit_path(#lawsuit)
end
end
Lawsuit Controller
class LawsuitsController < ApplicationController
before_action :set_lawsuit, only: [:show]
def index
#lawsuits = Lawsuit.paginate(:page => params[:page], :per_page => 8)
end
def show
begin
#blob = Lawsuit.get_blob_for_document(#lawsuit.document_number)[1]
rescue
#blob = "Cannot load document!"
flash[:error] = "Cannot load document!"
end
#lawsuit = Lawsuit.find(params[:id])
#suit = #lawsuit.suits.build
end
private
def set_lawsuit
#lawsuit = Lawsuit.find(params[:id])
end
def lawsuit_params
params.require(:lawsuit).permit(:document_number, :region, :court, :noted)
end
end
Modify view as follows
<%= form_with(model: [:lawsuit, #suit]) do |f| %>
<fieldset>
<legend>New Suit</legend>
</fieldset>
<br />
<% if #suit.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#suit.errors.count, "error") %>
<%= "prohibited this suit from being saved:" %>
</h2>
<ul></ul>
<% #suit.errors.full_messages.each do |message| %>
<li>
<%= message %>
</li>
<% end %>
</div>
<% end %>
<div class="form-group">
<%= f.label :claim %>
<%= f.text_field :claim, class: 'form-control', placeholder: 'Name' %>
</div>
<div class="form-group">
<%= f.label :sentence %>
<%= f.text_area :sentence, class: 'form-control', placeholder: 'Sentence' %>
</div>
<div class="form-group">
<%= f.label :result %>
<%= f.select(:result, [['Not Favorable', false], ['Favorable', true]], {}, {class: 'form-control'}) %>
</div>
<%= button_tag type: 'submit', class: "btn btn-primary float-right" do %>
<i class="fa fa-plus" aria-hidden="true"></i>
Create
<% end %>
<% end %>
note you should build #suit object from controller action first
#suit = #lawsuit.suits.build
and you controller should be
class SuitsController < ApplicationController
before_action :set_suit, only: [:show]
def new
end
def create
#lawsuit = Lawsuit.find(params[:lawsuit_id])
#suit = #lawsuit.suits.build(suit_params)
if #suit.save
flash[:notice] = "Suit created successfully"
redirect_to lawsuit_path(#lawsuit)
else
render :form
end
end
Or
If you want to display flash message then you should write following code on view
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>"><%= value %></div>
<% end %>

How does my show page need to be written in order to display data?

I am a newbie to the world of Ruby on Rails and I am developing a form that is dropdown in nature for the first time and you can see the code here in _form.html.erb:
<%= simple_form_for(#job, html: {class: 'form-horizontal'}) do |f| %>
<div class="control-group">
<%= f.label "Poster:", class: 'control-label' %>
<div class="controls">
<%= f.select(:status, options_for_select([['Nick Maloney','Nick Maloney'],
['Peter Brown','Peter Brown'],['Jen Morris','Jen Morris']])) %>
</div>
</div>
<div class="control-group">
<%= f.label "Category:", class: 'control-label' %>
<div class="controls">
<%= f.select(:status, options_for_select([['Landscaping','Landscaping'],
['Babysitting','Babysitting'],['Tree planting','Tree planting']])) %>
</div>
</div>
<div class="control-group">
<%= f.label "Location:", class: 'control-label' %>
<div class="controls">
<%= f.select(:status, options_for_select([['Dorchester','Dorchester'],
['Roxbury','Roxbury'],['Mattapan','Mattapan']])) %>
</div>
</div>
<div class="control-group">
<%= f.label "Status:", class: 'control-label' %>
<div class="controls">
<%= f.select(:status, options_for_select([['New','New'],
['Pending','Pending'],['Complete','Complete']])) %>
</div>
</div>
<%= f.input :description, label: "Job Description" %>
<%= f.submit 'Add Job', class: 'btn btn-default' %>
<% end %>
When I click on 'Add Job', it takes me to a blank screen which I have not been able to resolve on my own.
I have changed the code around a view times in the views/show.html.erb. I have had this:
<h1><%= #job.poster %></h1>
<p><%= #job.category %></p>
<p><%= #job.location %></p>
and this:
<tbody>
<% #job.each do |job| %>
<tr>
<td><%= job.poster %></td>
</tr>
<% end %>
</tbody>
and I continue to get a blank screen or if I went to my jobs_controller.rb and developed it like this:
class JobsController < ApplicationController
before_action :find_job, only: [:show, :edit, :update, :destroy]
def index
# #job = Job.all
end
def show
#job = Job.find_job(jobs_params[:id])
end
def new
#job = Job.new
end
def create
#job = Job.new(jobs_params)
if #job.save
redirect_to #job, notice: 'Your job was successfully added'
else
render "New"
end
end
def edit
end
def update
end
def destroy
end
private
def jobs_params
params.require(:job).permit(:poster, :category, :location, :status, :description)
end
def find_job
#job = Job.find(params[:id])
end
end
I would get an undefined method for 'poster' for ActiveRecord object, but if I remove the code in the show action, I just get a blank page. I am out of solutions here and I have looked on SO, but nothing resembled a solution for me.
My routes.rb file looks like this:
Rails.application.routes.draw do
resources :jobs
root 'jobs#index'
end
I changed the show action to reflect this:
def show
#job = Job.find(jobs_params[:id])
end
then I got a param is missing or the value is empty: job.
I did a rails console and I have this:
Job Load (1.1ms) SELECT "jobs".* FROM "jobs" LIMIT ? [["LIMIT", 11]] => #<ActiveRecord::Relation [#<Job id: 1, poster: nil, category: nil, location: nil, status: "New", description: "Your job is to plant trees all over the Dorchester...", created_at: "2017-08-01 10:29:40", updated_at: "2017-08-01 10:29:40">]>
I don't understand why I have nil on everything except description.
It seems that every form input like this:
<div class="control-group">
<%= f.label "Poster:", class: 'control-label' %>
<div class="controls">
<%= f.select(:status, options_for_select([['Nick Maloney','Nick Maloney'],
['Peter Brown','Peter Brown'],['Jen Morris','Jen Morris']])) %>
</div>
Gave me a nil in the rails console and only this one:
<%= f.input :description, label: "Job Description" %>
successfully inputted data, so something is wrong with the code for f.select, but I am not sure what.
change this
def show
#job = Job.find_job(jobs_params[:id])
end
to this
def show
end
The #job record is retrieved for you by the before_action
And use this in the show.html.erb
<h1><%= #job.poster %></h1>
<p><%= #job.category %></p>
<p><%= #job.location %></p>
Try to Replace your _form.html.erb with
<%= simple_form_for(#job, html: {class: 'form-horizontal'}) do |f| %>
<div class="control-group">
<%= f.label "Poster:", class: 'control-label' %>
<div class="controls">
<%= f.select(:poster, options_for_select([['Nick Maloney','Nick Maloney'],
['Peter Brown','Peter Brown'],['Jen Morris','Jen Morris']])) %>
</div>
</div>
<div class="control-group">
<%= f.label "Category:", class: 'control-label' %>
<div class="controls">
<%= f.select(:category, options_for_select([['Landscaping','Landscaping'],
['Babysitting','Babysitting'],['Tree planting','Tree planting']])) %>
</div>
</div>
<div class="control-group">
<%= f.label "Location:", class: 'control-label' %>
<div class="controls">
<%= f.select(:location, options_for_select([['Dorchester','Dorchester'],
['Roxbury','Roxbury'],['Mattapan','Mattapan']])) %>
</div>
</div>
<div class="control-group">
<%= f.label "Status:", class: 'control-label' %>
<div class="controls">
<%= f.select(:status, options_for_select([['New','New'],
['Pending','Pending'],['Complete','Complete']])) %>
</div>
</div>
<%= f.input :description, label: "Job Description" %>
<%= f.submit 'Add Job', class: 'btn btn-default' %>
<% end %>
In controller
def show
end
show.html.erb
<h1><%= #job.poster %></h1>
<p><%= #job.category %></p>
<p><%= #job.location %></p>
You got
Job id: 1, poster: nil, category: nil, location: nil, status:
"New", description: "Your job is to plant trees all over the
Dorchester..."
because by mistek you have used :status in every select in _form.html.erb
Remove this line from the show action in your JobsController :
#job = Job.find_job(jobs_params[:id])

No route matches [POST] "/contacts/new" Ruby on Rails

I'm building an interactive website through Cloud9 using a tutorial online. We are using bootstrap, JavaScript, ruby on rails, html, and scss. However, I am currently stuck. Whenever I click 'submit'...I get a Routing Error page. None of the information is stored in my db.
routes.rb
Rails.application.routes.draw do
root to: 'pages#home'
get 'about', to: 'pages#about'
resources :contacts
end
contacts_controller.rb
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(contact_params)
if #contact.save
redirect_to new_contact_path, notice: "Message sent."
else
redirect_to new_contact_path, notice: "Error occured."
end
end
private
def contact_params
params.require(:contact).permit(:name, :email, :comments)
end
end
contacts/new.html.erb
<div class="container">
<div class="row">
<h3 class="text-center">Contact Us</h3>
<div class="col-md-4 col-md-offset-4">
<%= flash[:notice] %>
<div class="well">
<%= form_for "contact" do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.text_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :comments %>
<%= f.text_area :comments, class: 'form-control' %>
</div>
<%= f.submit 'Submit', class: 'btn btn-default' %>
<% end %>
</div>
</div>
</div>
</div>
I followed the instructions exactly, and I have no idea what is wrong or what to change. Can someone help before I rip my hair out?
You need to change
<%= form_for "contact" do |f| %>
to
<%= form_for #contact do |f| %>
Full code
<div class="container">
<div class="row">
<h3 class="text-center">Contact Us</h3>
<div class="col-md-4 col-md-offset-4">
<%= flash[:notice] %>
<div class="well">
<%= form_for #contact do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.text_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :comments %>
<%= f.text_area :comments, class: 'form-control' %>
</div>
<%= f.submit 'Submit', class: 'btn btn-default' %>
<% end %>
</div>
</div>
</div>
</div>

How to create an error message when users enter incorrect inputs on registration or form submission

I have two forms on my rails app that require a user to enter a code to confirm that they belong to a school and in the other form a code for a classroom. Every time a user enters or leaves the code blank I get this error message:
First argument in form cannot contain nil or be empty
It's always in the create method of the controller so I must not have the correct syntax.
Here are the two controllers where the error occurs.
Registration Controller
class RegistrationsController < Devise::RegistrationsController
skip_before_filter :verify_authenticity_token, :only => :create
def update
super
end
def new
super
end
def create
code = params[:user][:code]
#school = School.where(:code => code).first
unless #school
flash[:error] = "School code not valid"
render :new
end
params[:user][:school_id] = #school.id
super
end
School controller
def create_teacher
authorize #school
params[:user][:school_id] = #school.id
params[:user][:role] = "teacher"
#teacher = User.create(teacher_params)
if #teacher.id.nil?
flash[:error] = #teacher.errors.full_messages
render :new_teacher
else
respond_with #school
end
end
How do I correct this issue so that it renders a flash error message?
EDIT Screen Shots of actual error. Note, they are both in the create method so I think it's an identical problem.
EDIT: Registration form for adding users to schools.
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h1>Sign up</h1>
</div>
<div class="panel-body">
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, autofocus: true, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :email, autofocus: true, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :school_code %>
<%# f.text_field :code, class: "form-control" %>
<input type="text" id="code" name="user[code]" value>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :password_confirmation, "Confirm Password" %>
<%= f.password_field :password_confirmation, class: "form-control" %>
</div>
<strong>Student</strong> <%= f.radio_button(:role, "user") %>
<div class="form-group">
<%= f.submit "Sign up", class: "btn btn-lg btn-primary" %>
</div>
<% end %>
</div>
<div class="panel-footer">
<%= render "devise/shared/links" %>
</div>
I think the issue is with your <%= form_for .. %> I can get the same error if I enter an invalid argument for that. For the school one try <%= form_for #school %> And make sure your new method in your controller (whichever one is rendering the page with the form) is making a new instance of the object,
def new
#school = School.new
end
And the same with the pin
Something like this may be what you're looking for
before_action :check_code, only: :create
...
def check_code
unless School.find_by school_code params[:school_code]
flash[:error] = "Invalid school code"
redirect_to new_reg_path
end
end
And to show the flash message
<% flash.each do |message_type, message| %>
<div class="alert alert-<%= message_type %>">
<%= message %>
</div>
<% end %>

ActiveModel Forbidden Error in Rails 4.0.0

Im working on a nested attribute form.
these are the two models..
Employee.rb
class Employee < ActiveRecord::Base
has_one :employee_info, :primary_key => :employeeID, foreign_key: :employeeID
accepts_nested_attributes_for :employee_info
end
EmployeeInfo.rb
class EmployeeInfo < ActiveRecord::Base
belongs_to :employee, primary_key: :employeeID, foreign_key: :employeeID
validates_uniqueness_of :employeeID
end
And i have my form in _form.html.rb
<%= form_for #employee, html: {class: "form form-horizontal validate-form", novalidate: "novalidate"} do |f| %>
<% if #employee.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger alert-dismissable">
<a class="close" data-dismiss="alert" href="#">×</a>
<h2><%= pluralize(#employee.errors.count, "error") %> prohibited this shop from being saved:</h2>
<ul>
<% #employee.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
</div>
<% end %>
<div class='form-group'>
<%= f.label :employeeID, class: 'col-md-2 control-label' %>
<div class='col-md-5'>
<%= f.text_field :employeeID, {class: 'form-control'} %>
</div>
</div>
<div class='form-group'>
<%= f.label :employee_name, class: 'col-md-2 control-label' %>
<div class='col-md-5'>
<%= f.text_field :employee_name, class: 'form-control' %>
</div>
</div>
<%= f.fields_for :employee_info do |ff| %>
<div class='form-group'>
<%= ff.label :hired, class: 'col-md-2 control-label' %>
<div class='col-md-5'>
<%= ff.text_field :hire_date, class: 'form-control' %>
</div>
</div>
<div class='form-group'>
<%= ff.label :terminated, class: 'col-md-2 control-label' %>
<div class='col-md-5'>
<%= ff.text_field :term_date, class: 'form-control' %>
</div>
</div>
<% end %>
<div class='form-actions form-actions-padding-sm'>
<div class='row'>
<div class='col-md-10 col-md-offset-2'><i class='icon-save custom-icon'></i>
<% if params[:action] == "new" %>
<%= f.submit "Create", class: 'btn btn-primary custom-button' %>
<% else %>
<%= f.submit "Update", class: 'btn btn-primary custom-button' %>
<% end %>
<%= link_to 'Cancel', shops_path, class: 'btn' %>
</div>
</div>
</div>
<% end %>
and the update method in controller
def update
respond_to do |format|
p "------------------------------"
p employee_params
if #employee.update(employee_params)
format.html { redirect_to #employee, notice: 'Employee was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #employee.errors, status: :unprocessable_entity }
end
end
end
where that p employee_params output in console is
{"employeeID"=>"103", "employee_name"=>"James Michule", "employee_info_attributes"=>{"hire_date"=>"1996-03-12 11:30:00 UTC", "term_date"=>"1996-03-12 11:30:00 UTC", "hourly_rate"=>"7.4", "address"=>"108 E. Jay", "phone_number1"=>"", "phone_number2"=>"", "zipcode"=>"65721", "state"=>"MO", "city"=>"Ozark", "id"=>"30"}}
and when i try to update i get an error..
error:
ActiveModel::ForbiddenAttributesError (ActiveModel::ForbiddenAttributesError):
app/controllers/employees_controller.rb:56:in `block in update'
app/controllers/employees_controller.rb:53:in `update'
What is wrong.? Please help
Rails 4 has features from the strong_parameters
so you can use
#employee.update_attributes(params[:employee], permit[:employee_attribute]
or you can do in following way
#employee.update_attributes(params[:employee].permit(:employeeID))
Your employees_controller
private
def employee_params
params.require(:employee).permit(:term_date, :hire_date)
end
Add term_date & hire_date in the employee_params method like the code above.
Hope it solves the issue.
P.S. And please read the topic "Rails Strong parameters" before creating the app on rails >= 4

Resources