ActiveModel Forbidden Error in Rails 4.0.0 - ruby-on-rails

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

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 %>

unable to do validations in 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

money-rails gem not allowing me to input cents into textbox

I am having problems with saving values to my database using the money-rails gem. Whenever I try and input a value with cents into the textbox (i.e. 20.22) it gives me an error saying "Please enter a valid value.The two nearest values are 20 and 21."
Model:
class VideoGame < ActiveRecord::Base
monetize :loose_price_cents, with_model_currency: :price_currency
monetize :cib_price_cents, with_model_currency: :price_currency
monetize :new_price_cents, with_model_currency: :price_currency
end
_form.html.erb:
<%= form_for(#video_game) do |f| %>
<% if #video_game.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#video_game.errors.count, "error") %> prohibited this video_game from being saved:</h2>
<ul>
<% #video_game.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :game %><br>
<%= f.text_field :game %>
</div>
<div class="field">
<%= f.label :loose_price %><br>
<%= f.number_field :loose_price %>
</div>
<div class="field">
<%= f.label :cib_price %><br>
<%= f.number_field :cib_price %>
</div>
<div class="field">
<%= f.label :new_price %><br>
<%= f.number_field :new_price %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
controller update function:
def update
respond_to do |format|
if #video_game.update(video_game_params)
format.html { redirect_to #video_game, notice: 'Video game was successfully updated.' }
format.json { render :show, status: :ok, location: #video_game }
else
format.html { render :edit }
format.json { render json: #video_game.errors, status: :unprocessable_entity }
end
end
end
I have gone into the rails console and changed values around manually, but it seems to base the error off of the database value (db value = 2011 cents, error = "Please enter a valid value.The two nearest values are 20.11 and 21.11.").
Any advice would be appreciated!
Edit:
I figured it out. By adding "step: 0.01" to the end of the number_field method it allows you to increase the value by .01 instead of the 1 by default. It should look like this instead:
<%= form_for(#video_game) do |f| %>
<% if #video_game.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#video_game.errors.count, "error") %> prohibited this video_game from being saved:</h2>
<ul>
<% #video_game.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :game %><br>
<%= f.text_field :game %>
</div>
<div class="field">
<%= f.label :loose_price %><br>
<%= f.number_field :loose_price, step: 0.01 %>
</div>
<div class="field">
<%= f.label :cib_price %><br>
<%= f.number_field :cib_price, step: 0.01 %>
</div>
<div class="field">
<%= f.label :new_price %><br>
<%= f.number_field :new_price, step: 0.01 %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

Validation errors not showing up - Rails 4

For some reason validation errors are not showing up.
my form
<%= form_for [#question.category, #question] do |f| %>
<% if #question.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#question.errors.count, "error") %> prohibited this question from being saved:</h2>
<ul>
<% #question.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field panel">
<%= f.label :question_type %><br>
<%= f.select :question_type, [ ["single","single"],["multiple","multiple"] ], selected: f.object.question_type %>
</div>
<div class="field panel">
<%= f.label :description %><br>
<%= f.text_field :description %>
</div>
<div class="field panel">
<%= f.label :image %><br>
<% if #question.image? %>
<div class="explanation-image text-center">
<%= image_tag #question.image_url(:resized) %>
<p>
<label>
<%= f.check_box :remove_image %>
Remove image
</label>
</p>
</div>
<% end %>
<%= f.file_field :image %>
<%= f.hidden_field :image_cache %>
</div>
<div class="field panel">
<%= f.label :explanation %><br>
<%= f.text_area :explanation, size: "30x10" %>
</div>
<div class="field panel">
<%= f.label :link_name %><br>
<%= f.text_field :link_name %>
</div>
<div class="field panel">
<%= f.label :link_url %><br>
<%= f.text_area :link %>
</div>
<div class="field panel">
<%= f.label :video_url %><br>
<%= f.text_area :video_url %>
</div>
<div class="field panel">
<%= f.label :category_id %><br><%= #category.title %>
<%= f.hidden_field :category_id %>
</div>
<div class="actions">
<br>
<%= f.submit 'Submit', class:"button round success" %> <%= link_to 'Back', category_questions_path, class: "button round alert" %>
</div>
<% end %>
this is the model
class Question < ActiveRecord::Base
belongs_to :category
has_many :choices
mount_uploader :image, ImageUploader
validates :description, length: {
minimum: 6
}
validates :link, presence: true
end
and parts of the controller
def edit
#category = Category.find(params[:category_id])
#question = #category.questions.find_by(id: params[:id])
end
def update
respond_to do |format|
if #question.update(question_params)
format.html { redirect_to category_question_url(#question.category, #question), notice: 'Question was successfully updated.' }
format.json { render :show, status: :ok, location: #question }
else
format.html {
#category = Category.find(params[:category_id])
#question = #category.questions.find_by(id: params[:id])
render action: :edit
}
format.json { render json: #question.errors, status: :unprocessable_entity }
end
end
end
the error messages code is directly from the scaffolding. i haven't touched it. if i try to edit a question and save it while lets say link field is empty it will reload the edit action correctly but no error message will pop up.
Any clues?
If it fails to save, you redefine the #question variable, before rendering out the page.
#question = #category.questions.find_by(id: params[:id])
this will delete the object which failed to save and was holding the validation errors, and replace it with the one loaded out of the database. Don't do this. I think if you just delete this line it might work ok.

Submit button does not work unless I refresh the page form_for Rails

I have an app that has a problem model and when I go to create a record the submit button does nothing. No errors given it just simply doesnt execute, unless I refresh the page and attempt add it again. The same happens when I go to update a record.
Here is my controller
class ProblemsController < ApplicationController
include Concerns::Votes
def index
#problems = Problem.all
end
def show
#problem = find_problem
end
def new
#problem = Problem.new
end
def edit
#problem = find_problem
end
def create
#problem = current_user.problems.new(problem_params)
#problem.save
redirect_to #problem
end
def update
#problem = find_problem
if #problem.update_attributes(problem_params)
redirect_to #problem
else
redirect_to #problem
end
end
private
def find_problem
#problem = Problem.find(params[:id])
end
def problem_params
params.require(:problem).permit(:name, :description, :url)
end
end
Here is my _form.html.erb partial that I am rendering on new.html
<div class="row">
<div class="large-12 columns">
<%= form_for #problem do |f| %>
<label>Name</label>
<%= f.text_field :name, placeholder: "Name your problem!" %>
</div>
<div class="large-8 columns">
<%= f.text_field :url, placeholder: "Link to any supporting material" %>
</div>
<div class="large-12 columns">
<%= f.text_area :description %>
</div>
<div class="large-12 columns">
<%= f.submit "Create" %>
</div>
</div>
<% end %>
I have resources :problems in my routes.
Here for good measure is my show.html.erb as well.
<%= div_for #problem do %>
<%= link_to 'Edit', edit_problem_path(#problem) %>
<h2><%= #problem.name %> (<%= #problem.cached_votes_score %>)</h2>
<a =href"<%= #problem.url %>"><%= #problem.url %></a>
<p><%= #problem.description %><p>
By <%= #problem.user.name %></br>
<a class="button"<%= link_to 'Up', {:controller => 'problems', :action => 'up_vote'}, {:method => :post } %></a>
<a class="button"<%= link_to 'Down', {:controller => 'problems', :action => 'down_vote'}, {:method => :post } %></a>
<%= link_to 'Edit', edit_problem_path(#problem) %> |
<%= link_to 'Back', problem_path %>
<% end %>
Here is my index.html.erb
<div class="row">
<div class="large-12 columns">
<% #problems.each do |problem| %>
<h1><small><%= problem.cached_votes_score %></small> <%= link_to problem.name, problem %></h1>
<% end %>
</div>
<%= link_to 'New Problem', new_problem_path %>
</div>
I really cant understand why it works if i refresh the page but otherwise it doesnt work at all.
Your HTML is invalid, the submit button is actually not nested under the form tag. Try changing your view code to this:
<div class="row">
<div class="large-12 columns">
<%= form_for #problem do |f| %>
<label>Name</label>
<%= f.text_field :name, placeholder: "Name your problem!" %>
<div class="large-8 columns">
<%= f.text_field :url, placeholder: "Link to any supporting material" %>
</div>
<div class="large-12 columns">
<%= f.text_area :description %>
</div>
<div class="large-12 columns">
<%= f.submit "Create" %>
</div>
<% end %>
</div>
</div>
I had same issue
Before
<%= simple_form_for(:schedule_list, url: schedulelists_create_with_block_path, :html => { novalidate: false}) do |f| %>
<div class="row">
<div class="col-md-12">
<%= f.button :submit, class: 'pull-right' %>
<%end%>
</div>
</div>
After
<%= simple_form_for(:schedule_list, url: schedulelists_create_with_block_path, :html => { novalidate: false}) do |f| %>
<div class="row">
<div class="col-md-12">
<%= f.button :submit, class: 'pull-right' %>
</div>
</div>
<%end%>

Resources