I have a form to create a new contact for an address book. In the model, the first_name and last_name fields are required:
models/contact.rb
class Contact < ApplicationRecord
[...]
validates :first_name, :last_name, presence: true
end
I have code which should show the messages if there are errors in the creation of the new contact:
views/contacts/_form.html.erb
<%= form_with model: @contact do |form| %>
<% if @contact.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(@contact.errors.count, "error") %> prevented this contact from being saved:
</h2>
<ul>
<% @contact.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= form.label :salutation %><br>
<%= form.select :salutation, options_for_select([['Mr.'], ['Mrs.'], ['Ms.'], ['Mx']]), class: "form-control" %><br>
<%= form.label :first_name, "First Name*" %><br>
<%= form.text_field :first_name, class: "form-control" %><br>
<%= form.label :middle_name, "Middle Name" %><br>
<%= form.text_field :middle_name, class: "form-control" %><br>
<%= form.label :last_name, "Last Name*" %><br>
<%= form.text_field :last_name, class: "form-control" %>
[...]
When I enter a contact with the first or last name missing, the contact is not created and the page stays on the form. However, no errors appear at the top of the view. I added some debugging in my controller and discovered that although the submission is invalid, there are no errors created:
controllers/contacts_controller.rb
[...]
def create
@contact = Contact.new(contact_params)
logger.debug "New contact: #{@contact.attributes.inspect}"
logger.debug "Contact should have errors: #{@contact.errors.any?}"
logger.debug "Contact should be invalid: #{@contact.invalid?}"
[...]
This produces the following response in the terminal:
Started POST "/contacts" for ::1 at 2020-09-28 11:42:47 +0200
Processing by ContactsController#create as JS
Parameters: {"authenticity_token"=>"2GBdtJXn77B9+IQuXg03C9HFgMS+ayzqP5lke49HcsvcM02L6lgyoGXuOtKL72mBzNsFU6EawC2dU+mN6RZzkA==", "contact"=>{"salutation"=>"Mrs.", "first_name"=>"Sue", "middle_name"=>"", "last_name"=>"", "ssn"=>"", "dob"=>"", "comment"=>""}, "commit"=>"Create Contact"}
New contact: {"id"=>nil, "salutation"=>"Mrs.", "first_name"=>"Sue", "middle_name"=>"", "last_name"=>"", "ssn"=>"", "dob"=>"", "comment"=>"", "created_at"=>nil, "updated_at"=>nil}
Contact should have errors: false
Contact should be invalid: true
Rendering contacts/new.html.erb within layouts/application
Rendered contacts/_form.html.erb (Duration: 4.7ms | Allocations: 1484)
Rendered contacts/new.html.erb within layouts/application (Duration: 5.0ms | Allocations: 1569)
[Webpacker] Everything's up-to-date. Nothing to do
Completed 200 OK in 70ms (Views: 20.1ms | ActiveRecord: 27.1ms | Allocations: 18926)
This is strange to me: Contact should have errors: false; Contact should be invalid: true As far as I know, my validation in my model is correct, and the submission is being recognized as invalid, but this doesn't translate to errors for some reason. What do I need to change?
Any help would be really great! Thank you for looking.
EDIT:
Here is the full create method, with the .save method included:
def create
@contact = Contact.new(contact_params)
if @contact.save
redirect_to @contact, notice: 'Contact was successfully created'
else
render 'new'
end
end
Here is the image of the webpage after attempting to submit an invalid request:
.save!and.create!that Rails will raise an RecordNotValid exception if the record is not valid.