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
Related
I'm a beginner in Rails, I have a Suplement controller and I can't create or edit a suplement (delete works fine). I'm not getting any errors, just nothing happens when I click and everything's working fine from the console. I tried everything I know (which is not much) and I couldn't find a question like this, similar answers didn't help. I'd appreciate any help, thanks!
class SuplementsController < ApplicationController
before_action :set_suplement, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
def index
#suplement = Suplement.all.order("created_at DESC")
end
def new
#suplement = Suplement.new
end
def create
#suplement = Suplement.new(suplement_params)
if #suplement.save
redirect_to '/suplements'
else
render '/suplements/new'
end
end
def show
end
def edit
end
def update
if #suplement.update(suplement_params)
redirect_to '/suplements'
else
redirect_to '/suplements/new'
end
end
def destroy
#suplement.destroy
redirect_to '/suplements'
end
private
def set_suplement
#suplement = Suplement.find(params[:id])
end
def suplement_params
params.require(:suplement).permit(:name,
:number_of_units,
:daily_dosage_in_units,
:number_of_days,
:suplement_cost
)
end
end
Here's a view:
<h1>Create new suplement</h1>
<%= form_for(#suplement) do |f| %>
<%= render 'form', suplement: #suplement %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
and here's a form partial:
<%= form_for(#suplement) do |f| %>
<% if #suplement.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#suplement.errors.count, "error") %> prohibited this suplement from being saved:</h2>
<ul>
<% #suplement.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :number_of_units %>
<%= f.text_field :number_of_units %>
</div>
<div class="field">
<%= f.label :daily_dosage_in_units %>
<%= f.text_area :daily_dosage_in_units %>
</div>
<div class="field">
<%= f.label :number_of_days %>
<%= f.text_area :number_of_days %>
</div>
<div class="field">
<%= f.label :suplement_cost %>
<%= f.text_area :suplement_cost %>
</div>
<% end %>
Also my models:
class Suplement < ApplicationRecord
belongs_to :user
validates :name,
:number_of_units,
:daily_dosage_in_units,
:number_of_days,
:suplement_cost,
presence: true
end
and
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :suplements
end
It looks like the problem is that you have 2 forms.
Uou have a form_for #suplement in your _form.html.erb file and also in your new.html.erb file. Try removing it from new.html.erb so your file looks like this
new.html.erb
<h1>Create new suplement</h1>
<%= render 'form', suplement: #suplement %>
_form.html.erb
<%= form_for(#suplement) do |f| %>
<% if #suplement.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#suplement.errors.count, "error") %> prohibited this suplement from being saved:</h2>
<ul>
<% #suplement.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :number_of_units %>
<%= f.text_field :number_of_units %>
</div>
<div class="field">
<%= f.label :daily_dosage_in_units %>
<%= f.text_area :daily_dosage_in_units %>
</div>
<div class="field">
<%= f.label :number_of_days %>
<%= f.text_area :number_of_days %>
</div>
<div class="field">
<%= f.label :suplement_cost %>
<%= f.text_area :suplement_cost %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
What I did is:
1) Deleted form_for and submit button inside new.html.erb
2) Added submit button in _form.html.erb, so the variable f is accessible
Also, since you are passing a variable #suplement to partial local variable suplement, you can use the variable suplement inside _form.html.erb file without the # sign
EDIT (Regarding comment):
Your getting User presence validation Error, because from Rails 5.0, belongs_to associations are automatically validated for presence.
If you do not need a user in your suplement object all the time then you should change your association to belongs_to :user, optional: true
OR
if you do need the user, and you always want it to be the current user logged in, then add this to your _form
<%=f.hidden_field :user_id, current_user.id %>
This will use Devise helper method to get the current logged in user and assign it to this hidden field. Don't forget to add this parameter in your controler suplement_params controller method
In the #edit of your controller, you need to set the value of the #suplement variable.
def edit
#suplement = Suplement.find(params[:id])
end
you should also include the above line as the first line in your #update method
def update
#suplement = Suplement.find(params[:id])
if #suplement.update_attributes(suplement_params)
# continued...
end
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
I'm building a rails app that has a an object that is created /nested underneath two objects.
Routes.rb
resources :pages do
resources :referralpages do
resources :rewards do
end
end
end
I've just added the rewards resource and have this for my form for creating a new reward
<%= form_for ([#referralpage, #reward]) do |f| %>
<% if #reward.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#reward.errors.count, "error") %> prohibited this reward from being saved:</h2>
<ul>
<% #reward.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= f.label :name %><br>
<%= f.text_field :name, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :level %><br>
<%= f.text_field :level, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :dscount %><br>
<%= f.text_field :discount, class: "form-control" %>
</div>
<div class="actions">
<%= f.submit class: "btn btn-primary" %>
</div>
<% end %>
I need help getting the form_for ([#referralpage, #reward]) portion working.
Here's the error message I'm getting when clicking the new reward button:
undefined method `referralpage_rewards_path'
<%= form_for ([#referralpage, #reward]) do |f| %>
my guess is that it's routing to the incorrect path. What's the proper syntax to get this to work?
I think it should render this path
new_page_referralpage_reward
The point of this feature is to render rewards in the referral/show.html.erb page
I have created an index partial in my rewards view file and am rendering it in the show action of the referralpages/show.html.erb file.
I think you cannot put more than one resource path in form_for which cause invalid path.
Why you want to put 2 resource path in form?
Do you plan to save the same data for referral & rewards Model?
If, yes use just one path and make a create method in your controller to save to other model.
From this point of view:
The point of this feature is to render rewards in the
referral/show.html.erb page
If you only plan to render the data of rewards to referral/show.html.erb,
in your referral controller
def show
#rewards = Reward.all #example
end
Unless, you have model relationships like:
#Reward Model
belongs_to :refferal
#Referral Model
has_many :rewards or has_one :reward
With model realtionship:
def show
#referal = Referral.all #example
end
show.html.erb View # iterate it:
<%for referral in #referral%>
<% referral.rewards %> # need to iterate if has many
or
<%= referral.reward... %>
<%end%>
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.
I would like to capture email addresses with this form:
I have decided to create a model only for this and use the views and controller for a different model that is serving only static assets (think: newsletter sign-up).
<%= form_for (#signup) do |f| %>
<% if #signup.errors.any? %>
<div id="error_explanation">
<p><%= pluralize(#signup.errors.count, "error") %> prohibited this post from being saved:</p>
<ul>
<% #signup.errors.full_messages.each do |user| %>
<li><%= user %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :email_address %><br />
<%= f.email_field_tag :email_address %>
</div>
<div class="actions">
<%= f.submit %>
</div>
How do I get this form to work? I get undefined method signups_path for #<#<Class:0x00000004f1feb0>:0x00000004f09a98> exception, which is understandable (its looking for a SignupsController by convention).
But I want the form to display in a separate controller I call PagesController and send it to the Signup model.
Additional Info:
I tried passing url: pages_path in the form and get the same exception.
# view inside PagesController
<div class="four columns">
<%= render 'form' %>
</div>
#stub of model
class PagesController < ApplicationController
def index
#signup = Signup.new
end
def create
#signup = Signup.new(params[:signup])
end
end
try:
<%= form_for #sighup, :url => {:controller => :pages, :action => :index} do |f| %>
and I hope you didn't forget the
<% end %>