Error messages are not displaying correctly in Rails - ruby-on-rails

else
object = record.is_a?(Array) ? record.last : record
raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object
object_name = options[:as] || model_name_from_record_or_class(object).param_key
apply_form_for_options!(record, object, options)
end
Hi, relatively new to Rails and programming in general. I'm getting this error when I try to submit a form with errors in them. It works perfectly fine when all the fields are filled in correctly, but if a form is missing something, it does not display the error like it should in this picture:
Instead, I get this:
Here is the code for the form:
<%= form_for(#quote) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Save a new quote..." %>
<%= f.text_field :author, placeholder: "Author:" %>
<%= f.text_field :source, placeholder: "Source:" %>
</div>
<%= f.submit "Save", class: "btn btn-primary" %>
<% end %>
Here is the code for the error messages:
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
The form contains <%= pluralize(object.errors.count, "error") %>.
</div>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
And here is the code for the QuotesController:
class QuotesController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
def create
#quote = current_user.quotes.build(quote_params)
if #quote.save
flash[:success] = "Quote saved!"
redirect_to root_url
else
render 'static_pages/home'
end
end
def edit
end
def destroy
end
private
def quote_params
params.require(:quote).permit(:content, :author, :source)
end
end
How do I fix it so that it renders errors correctly like in the first picture?
* It turns out the code is actually working but the only problem is that the homepage of my site runs two forms that calls on the shared/error_messages which is why I'm guessing they conflict. When I remove one of the forms, the other form works fine. Any ideas on how to run two forms on the same page? *

Related

Rails - param is missing or the value is empty - even with matching names

When I use my form to enter data into the database I get this error:
param is missing or the value is empty: application
My controller code is:
def new
#application = RegisteredApplication.new
end
def create
#application = RegisteredApplication.new(application_params)
#application.user = current_user
if #application.save
redirect_to #application, notice: "Your new application is now registered"
else
flash.now[:alert] = "Error registering application. Please try again."
render :new
end
end
private
def application_params
params.require(:application).permit(:name, :url)
end
The new.html.erb file:
<h1>Register New Application</h1>
<%= render partial: 'form', locals: { application: #application } %>
And the _form.html.erb file:
<%= form_for(application) do |f| %>
<% if application.errors.any? %>
<div class="alert alert-danger">
<h4><%= pluralize(application.errors.count, "error") %>.</h4>
<ul>
<% application.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control', placeholder: "Enter application name" %>
</div>
<div class="form-group">
<%= f.label :url %>
<%= f.text_field :url, rows: 8, class: 'form-control', placeholder: "Enter application url" %>
</div>
<div class="form-group">
<%= f.submit "Save", class: 'btn btn-success' %>
</div>
<% end %>
Most people posting this particular question don't match the name in the 'create' method with what's in require(). But, don't all my names match?
For further information, if I remove require(:application) so that it looks like this:
params.permit(:name, :url)
the above allows it to go to the database, however, it doesn't pass the information. It creates a row in the DB, but the fields are nil.
Because #application is an instance of RegisteredApplication I am pretty sure that your params would look like this:
{ registered_application: { name : # ...
You can see the format of the parameter hash in your log file.
Therefore your application_params method must look like this:
def application_params
params.require(:registered_application).permit(:name, :url)
end

Getting "param is missing or the value is empty: post" explained below

when i click new post and try to save a new post it gives me that error, then i go to the controller :
private
def posts_params
params.require(:post).permit(:title, :description)
end
and change 'require(:post)' to 'require(:posts' then i works
but then i try to edit the new post i just created and when i click to save it it gives me the same error, then i just change it back to 'required(:post)' and it works, why this is happening ? it's like a loop, if one works the other doesn't and to work i have to change that one thing
Controller:
class PostsController < ApplicationController
def index
#posts = Post.all
end
def edit
#posts = Post.find(params[:id])
end
def update
#posts = Post.find(params[:id])
if #posts.update(posts_params)
redirect_to #posts
else
render 'edit'
end
end
def new
#posts = Post.new
end
def create
#posts = Post.new(posts_params)
if #posts.save
redirect_to #posts
else
render 'new'
end
end
def show
#posts = Post.find(params[:id])
end
private
def posts_params
params.require(:post).permit(:title, :description)
end
end
view edit:
<h1>Editing post</h1>
<%= form_for(#posts) do |f| %>
<% if #posts.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#posts.errors.count, "error") %> prohibited
this post from being saved:
</h2>
<ul>
<% #posts.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :description %><br>
<%= f.text_area :description %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Back', posts_path %>
view new:
<h1>New Article</h1>
<%= form_for :posts, url: posts_path do |f| %>
<% if #posts.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#posts.errors.count, "error") %> prohibited
this post from being saved:
</h2>
<ul>
<% #posts.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :description %><br>
<%= f.text_area :description %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Back', posts_path %>
can someone point the problem out ?
You are mixing
form_for(#posts) do |f|
and
form_for :posts, url: posts_path
In your forms.
the :posts version will generate params[:posts] and the #posts version will generate params[:post]. Hence the issue you are seeing. Make sure you posts_params is as follows.
def posts_params
params.require(:post).permit(:title, :description)
end
then just change both of your forms to be
<%= form_for(#posts) do |f| %>
rails will figure out which to call automatically for you, so you will not have to specify the paths..
On a side note, I would probably change #posts to be #post everywhere but the index action, just so that it makes more sense, Since in new,edit,etc.. you are dealing with a singular post.
Since rails is looking at the Model/class of the variable when generating the routes (When given an instance variable) the name of the variable doesn't matter to the framework, but makes it easier (in my opinion) for the programmer to understand

How to show error message on rails views?

I am newbie in rails and want to apply validation on form fields.
myviewsnew.html.erb
<%= form_for :simulation, url: simulations_path do |f| %>
<div class="form-group">
<%= f.label :Row %>
<div class="row">
<div class="col-sm-2">
<%= f.text_field :row, class: 'form-control' %>
</div>
</div>
</div>
.....
Simulation.rb
class Simulation < ActiveRecord::Base
belongs_to :user
validates :row, :inclusion => { :in => 1..25, :message => 'The row must be between 1 and 25' }
end
simulation_controller.rb
class SimulationsController < ApplicationController
def index
#simulations = Simulation.all
end
def new
end
def create
#simulation = Simulation.new(simulation_params)
#simulation.save
redirect_to #simulation
end
private
def simulation_params
params.require(:simulation).permit(:row)
end
I want to check the integer range of row field in model class and return the error message if it's not in the range. I can check the range from above code but not able to return the error message
Thanks in advance
The key is that you are using a model form, a form that displays the attributes for an instance of an ActiveRecord model. The create action of the controller will take care of some validation (and you can add more validation).
Controller re-renders new View when model fails to save
Change your controller like below:
def new
#simulation = Simulation.new
end
def create
#simulation = Simulation.new(simulation_params)
if #simulation.save
redirect_to action: 'index'
else
render 'new'
end
end
When the model instance fails to save (#simulation.save returns false), then the new view is re-rendered.
new View displays error messages from the model that failed to save
Then within your new view, if there exists an error, you can print them all like below.
<%= form_for #simulation, as: :simulation, url: simulations_path do |f| %>
<% if #simulation.errors.any? %>
<ul>
<% #simulation.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
<div class="form-group">
<%= f.label :Row %>
<div class="row">
<div class="col-sm-2">
<%= f.text_field :row, class: 'form-control' %>
</div>
</div>
</div>
<% end %>
The important part here is that you're checking whether the model instance has any errors and then printing them out:
<% if #simulation.errors.any? %>
<%= #simulation.errors.full_messages %>
<% end %>
Do this -
<%= form_for :simulation, url: simulations_path do |f| %>
<% if f.object.errors.any? %>
<ul>
<% if f.object.errors.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
..........
<% end %>
You just need to add this code to the view file (myviewsnew.html.erb):
<%= error_messages_for :simulation %>
Check complete syntax of error_messages_for in http://apidock.com/rails/ActionView/Helpers/ActiveRecordHelper/error_messages_for

using partials in Hartl's Rails tutorial, undefined variable method 'object'

I am going through Hartl's Rails tutorial and have been stuck at a rather frustrating point in chapter 10.
<%= form_for(#micropost) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose new micropost..." %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
Using this yields this error
ActionView::Template::Error:
undefined local variable or method `object' for #<#<Class:0x00000106cad990>:0x00000103395f18>
I have been through it a few times and I am struggling to see where I am going wrong. I've referred to other SO posts but so far none have offered any solution.
Here is
_error_messages.html.erb
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(object.errors.count, "error") %>.
</div>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
controller.rb
class MicropostsController < ApplicationController
before_action :signed_in_user
def create
#micropost = current_user.microposts.build(micropost_params)
if #micropost.save
flash[:success] = "Micropost created!"
redirect_to root_url
else
render 'static_pages/home'
end
end
def destroy
end
private
def micropost_params
params.require(:micropost).permit(:content)
end
end
home controller
def home
#micropost = current_user.microposts.build if signed_in?
end
If i am passing 'object' as the argument through the partial it should work no?
Thanks

Using a form to populate a database and land on a page with the information submitted

I have a form on my new view that takes in "url" and "title". When I submit my "url" & "title" I am taken to a blank create view. Ideally I would like to populate my database and land on a page that shows the title and link for that project.
This is my controller as it stands:
class LinksController < ApplicationController
def index
end
def new
#link = Link.new
end
def create
end
end
And this is the form:
<h1> This is New page for links </h1>
<%= form_for(#link) do |f| %>
<% if #link.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#link.errors.count, "error") %> prohibited this link from being saved:</h2>
<ul>
<% #link.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :url %><br />
<%= f.text_field :url %>
</div>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
How would I go about creating my methods(actions) to populate the database and then render what I am seeking? Ideally I'd like to see the flow behind how to think about the problem and the final code so that I can reverse engineer it.As long as I see it once I should be able to do it on my own next time.
You just have to do this
def create
#link = Link.new(params[:link])
if #link.save
redirect_to #link
else
render :new
end
end
def show
#link = Link.find(param[:id])
end
In routes.rb you will want to make sure you have the routes for this controller and its actions.
resources :links
That will provide you the standard CRUD HTTP methods with matching routes.

Resources