So im learning rails, and following the rails getting started guide (I've actually done the "blog app" on the Udemy rails course, but im making sure I can write it from scratch first before moving on).
Anyways, i've gotten Delete/Create running, but I was adding validation...and while the validation works my errors aren't showing up.
Right now my pages are super simple:
new.html.erb
<% if #user.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#user.errors.count, "error") %> prohibited this user from being saved
</h2>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= form_with scope: :user, url: users_path, local: true do |form| %>
<p>
<%= form.label :username %><br>
<%= form.text_field :username %>
</p>
<p>
<%= form.label :name %><br>
<%= form.text_field :name %>
</p>
<p>
<%= form.label :age %><br>
<%= form.number_field :age %>
</p>
<p><%= form.submit %></p>
<% end %>
users_controller
class UsersController < ApplicationController
def index
#users = User.all
end
def new
#user = User.new
end
def edit
#user = User.find(params[:id])
end
def create
#user = User.new(params.require(:user).permit(:username,:name,:age))
if #user.save
redirect_to users_path
else
render 'new'
end
end
def update
end
def destroy
#user = User.find(params[:id])
#user.destroy
redirect_to users_path
end
end
So the weird thing if I go into my network tab in dev tools I can see this show up in the response tab:
<div id="error_explanation">
<h2>
1 error prohibited this user from being saved
</h2>
<ul>
<li>Username has already been taken</li>
</ul>
</div>
But it doesn't show up in "elements" in Chrome dev tools. I've restarted rails....so Im really not sure why the elements are not showing up. I DO have bootstrap 4.00 beta installed, but not sure why that would matter. This is rails 5.1.4 btw.
This is because you are not getting the same #user in the <% if #user.errors.any? %>
Try this :
<%= form_with scope: :user, url: users_path, local: true do |form| %>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#user.errors.count, "error") %> prohibited this user from being saved
</h2>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= form.label :username %><br>
<%= form.text_field :username %>
</p>
<p>
<%= form.label :name %><br>
<%= form.text_field :name %>
</p>
<p>
<%= form.label :age %><br>
<%= form.number_field :age %>
</p>
<p><%= form.submit %></p>
<% end %>
Related
The Seller Profile has one seller. I am trying to post the seller profile details and assigning the seller_id to the current_seller. I am however, running into this error. I don't understand why the error says missing parameter because it seems all the needed params have being provided.
Error is get is ActionController::ParameterMissing (param is missing or the value is empty: seller_profiles
def create
#seller_profile = SellerProfile.new(seller_profile_params)
#seller_profile.seller = current_seller
respond_to do |format|
if #seller_profile.save
format.html { redirect_to root_path, notice: 'Seller profile was successfully created.' }
def seller_profile_params
params.require(:seller_profile).permit(:first_name, :other_name, :last_name, :email)
end
<%= form_tag seller_seller_profiles_path do |form| %>
<% if seller_profile.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(seller_profile.errors.count, "error") %> prohibited this seller_profile from being saved:</h2>
<ul>
<% seller_profile.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= label_tag :first_name %>
<%= text_field_tag :first_name %>
</div>
<div class="field">
<%= label_tag :other_name %>
<%= text_field_tag :other_name %>
</div>
<div class="field">
<%= label_tag :last_name %>
<%= text_field_tag :last_name %>
</div>
<div class="field">
<%= label_tag :email %>
<%= text_field_tag :email %>
</div>
<div class="actions">
<%= submit_tag %>
</div>
<% end %>
resources :sellers, only: [:new, :create, :show, :index, :destroy] do
resources :seller_profiles
end
You should use the form_for or the form_with helpers instead of form_tag. Those helper methods will take care of adding the wrapping seller_profile key.
<%= form_for seller_profile do |form| %>
<% if seller_profile.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(seller_profile.errors.count, "error") %> prohibited this seller_profile from being saved:</h2>
<ul>
<% seller_profile.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :first_name %>
<%= form.text_field :first_name %>
</div>
<div class="field">
<%= form.label :other_name %>
<%= form.text_field :other_name %>
</div>
... replicate the same change for the rest of the fields ...
<div class="actions">
<%= form.submit %>
</div>
<% end %>
If the error is (param is missing or the value is empty: seller_profiles, it's because you require :seller_profile, not :seller_profiles in your params.require
I'm using Rails 6.0.3.4 and Ruby 2.7.2. Using the Rails getting started tutorial as an example, I'm wondering how to show form validation errors of an associated model.
Show page
<p>
<strong>Title:</strong>
<%= #article.title %>
</p>
<p>
<strong>Text:</strong>
<%= #article.text %>
</p>
<h2>Comments</h2>
<%= render #article.comments %>
<h2>Add a comment:</h2>
<%= render 'comments/form' %>
<%= link_to 'Edit', edit_article_path(#article) %> |
<%= link_to 'Back', articles_path %>
Comments form (this is the form in question)
<%= form_with(model: [ #article, #article.comments.build ], local: true) do |form| %>
<p>
<%= form.label :commenter %><br>
<%= form.text_field :commenter %>
</p>
<p>
<%= form.label :body %><br>
<%= form.text_area :body %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
Models
class Comment < ApplicationRecord
belongs_to :article
validates :commenter, presence: true
end
class Article < ApplicationRecord
has_many :comments, dependent: :destroy
validates :title, presence: true,
length: { minimum: 5 }
end
For a single model articles form, errors could be shown like this.
<% if #article.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#article.errors.count, "error") %> prohibited
this article from being saved:
</h2>
<ul>
<% #article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
How do I show errors for the comments form? When I submit a comment without a commentor, it does not save, so validations are happening, but I'm not sure how to show errors for this type of form.
<% if #???????.errors.any? %> ###### What do I say here to get the comment errors?
<div id="error_explanation">
<h2>
<%= pluralize(#?????.errors.count, "error") %> prohibited
this article from being saved:
</h2>
<ul>
<% #?????.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
1. Create a reusable partial for errors
# app/views/shared/_errors.html.erb
<div class="error_explanation">
<h2><%= pluralize(object.errors.count, "error") %> prohibited
this <%= object.model_name.singular %> from being saved:</h2>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
And a little helper method:
# app/helpers/application_helper.rb
module ApplicationHelper
# Displays the errors for a model instance if there are any
def display_errors_for(object)
return unless object.errors.any?
render partial: 'shared/errors',
locals: { object: object }
end
end
2. Get the object from the form builder
You can always access the model wrapped by the form builder instance through the #object method instead of using a instance variable:
<%= form_with(model: [ #article, #comment ], local: true) do |form| %>
# ...
<%= display_errors_for(form.object) %>
<% end %>
And like magic you can add errors to any form with a single line.
Do not use #article.comments.build. That will always bind the form to a new instance of comment instead of displaying the errors! It will also remove anything the user entered into the form... Assign the variable in the controller. I have no idea how this snuck its way into the guides.
class ArticlesController < ApplicationController
def show
#article = Article.find(params[:id])
#comment = #article.comments.new
end
end
I'm working on a project in Ruby on Rails (Ruby v.2.2.8, Rails 5.1.4) and have encountered a very strange issue.
For my show method in the controller, I have:
def show
#county = County.find(params[:id])
end
And it works. For update, I have.
def update
#county = County.find(params[:id])
if #county.update(county_params)
redirect_to #county
else
render 'edit'
end
end
In my 'edit', I consistently get an error that #county is nil. The error page indicates that the parameters are being passed as:
{'id'=>4}
as an example. When I use find_by from the rails console, the item is found.
Is there something here I'm missing?
ETA: View Code
<%= form_with model: #county, local: true do |form| %>
<% if #county.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#county.errors.count, "error") %> prohibited
this county from being saved:
</h2>
<ul>
<% #county.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= form.label :name %><br>
<%= form.text_field :name %>
</p>
<p>
<%= form.label :shortname %><br>
<%= form.text_field :shortname %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
ETA Routes for Counties:
counties GET /counties(.:format) counties#index
POST /counties(.:format) counties#create
new_county GET /counties/new(.:format) counties#new
edit_county GET /counties/:id/edit(.:format) counties#edit
county GET /counties/:id(.:format) counties#show
PATCH /counties/:id(.:format) counties#update
PUT /counties/:id(.:format) counties#update
DELETE /counties/:id(.:format) counties#destroy
The error occurs at /counties/:id/edit
How is your edit action in your controller?
You should define #county as well
def edit
#county = County.find(params[:id])
end
I am creating my first app, simple blog, and I don't know how to show error messages for nested resource(comments) that doesn't pass validation.
this is create action for comments:
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.create(comment_params)
redirect_to post_path(#post)
end
this is comment form:
<%= form_for([#post, #post.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :text %><br />
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
I tried with:
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.build(comment_params)
if #comment.save
redirect_to post_path(#post)
else
render '/comments/_form'
end
end
and:
<% if #comment.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#comment.errors.count, "error") %> prohibited
this comment from being saved:
</h2>
<ul>
<% #comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
But I don't know whats wrong.
You can't render a partial from a controller. A better alternative is just to create a new view.
class CommentsController
def create
if #comment.save
redirect_to post_path(#post), success: 'comment created'
else
render :new
end
end
end
app/views/comments/new.html.erb:
<% if #comment.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#comment.errors.count, "error") %> prohibited
this comment from being saved:
</h2>
<ul>
<% #comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= render partial: 'form', comment: #comment %>
app/views/comments/_form.html.erb:
<%= form_for([#post, local_assigns[:comment] || #post.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :text %><br />
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
I have the following view page in my test_app:
<p id="notice"><%= notice %></p>
<p>
<strong>Box count:</strong>
<%= #job.box_count %>
</p>
<p>
<strong>Install date:</strong>
<%= #job.install_date %>
</p>
<%= link_to "Back", :back %>
I have the following ruby code in my jobs_controller show method:
def show
#job = Job.find(params[:job_id])
end
The parameters being passed through to the view are ("customer_id" and "id" for the job) as follows:
{"customer_id"=>"1", "id"=>"23"}
When I load the view for any job, I get the following error:
Couldn't find Job without an ID
I must have an error in my show method, but I am unsure exactly what I am doing wrong.
Any ideas?
It looks as though the issue is that my form is not saving the data to the table, here is my form:
<%= form_for([#customer, #job]) do |f| %>
<% if #job.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#job.errors.count, "error") %> prohibited this job from being saved:</h2>
<ul>
<% #job.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :box_count %><br>
<%= f.number_field :box_count %>
</div>
<div class="field">
<%= f.label :install_date %><br>
<%= f.text_field :install_date %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Any idea why the data is not being saved?
You should be using :id, not :job_id:
def show
#job = Job.find(params[:id])
end