0

I am on chapter 19 of the learn rails book by Daniel Kehoe and have created a form. However when I deliberately make errors in order to test the validations no messages appear. for example when I submit an empty form it simply renders a new form without the error message and when I enter an incorrect email address, without '@' again it seems to accept my inputs with no errors. so my question is why are the validations not raising any error messages?

here is my model contact.rb

class Contact
    include ActiveModel::Model
    attr_accessor :name, :email, :content

    validates_presence_of :name
    validates_presence_of :email
    validates_presence_of :content
    validates_format_of :email,
        with: /\A[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}\z/i
    validates_length_of :content, :maximum => 500
end

application layout application.html.erb

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><%= content_for?(:title) ? yield(:title) : "Workspace" %></title>
    <meta name="description" content="<%= content_for?(:description) ? yield(:description) : "Workspace" %>">
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => 'reload' %>
    <%= csrf_meta_tags %>
  </head>
  <body>
    <header>
      <%= render 'layouts/navigation' %>
    </header>
    <main role="main">
      <%= render 'layouts/messages' %>
      <%= yield %>
    </main>
  </body>
</html>

form view new.html.erb

<% content_for :title do %>Contact<% end %>
<h3>Contact</h3>
<div class="form">
    <%= form_with(model: @contact) do |form| %>
        <%= form.label :name %>
        <%= form.text_field :name, autofocus: true %>
        <br/>
        <br/>
        <%= form.label :email %>
        <%= form.email_field :email %>
        <br/>
        <br/>
        <%= form.label 'message' %>
        <%= form.text_area :content, size: '40x5' %>
        <br/>
        <br/>
        <%= form.submit 'Submit', class: 'submit' %>
    <% end %>
</div>

contacts_controller.rb

    class ContactsController < ApplicationController

  def new
  @contact = Contact.new
  end

  def create
    @contact = Contact.new(secure_params)
    if @contact.valid?
      # TODO send message
      flash[:notice] = "Message sent from #{@contact.name}."
      redirect_to root_path
    else
      render :new
    end
  end

  private
    def secure_params
      params.require(:contact).permit(:name, :email, :content)
    end
end

layout helper _messages.html.erb

<%# Rails flash messages styled for Bootstrap 3.0 %>
<% flash.each do |name, msg| %>
  <% if msg.is_a?(String) %>
    <div class="alert alert-dismissible alert-<%= name.to_s == 'notice' ? 'success' : 'danger' %>">
      <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
      <%= content_tag :div, msg, :id => "flash_#{name}" %>
    </div>
  <% end %>
<% end %>

EDIT 1:

The validations seem to work when I create a new contact in the console manually. But the app is not validating them when created through the app form. see below for my experiment with creating a new contact.

2.3.4 :002 > c=Contact.new
 => #<Contact:0x000000055741a8> 
2.3.4 :003 > c
 => #<Contact:0x000000055741a8> 
2.3.4 :004 > c.name='biggles2'
 => "biggles2" 
2.3.4 :005 > c
 => #<Contact:0x000000055741a8 @name="biggles2"> 
2.3.4 :006 > c.valid?
 => false 
2.3.4 :007 > c.email='biggldy@boggldy.com'
 => "biggldy@boggldy.com" 
2.3.4 :008 > c
 => #<Contact:0x000000055741a8 @name="biggles2", @validation_context=nil, @errors=#<ActiveModel::Errors:0x0000000554a948 @base=#<Contact:0x000000055741a8 ...>, @messages={:email=>["can't be blank", "is invalid"], :content=>["can't be blank"]}, @details={:email=>[{:error=>:blank}, {:error=>:invalid, :value=>nil}], :content=>[{:error=>:blank}]}>, @email="biggldy@boggldy.com"> 
2.3.4 :009 > c.email
 => "biggldy@boggldy.com" 
2.3.4 :010 > c.name
 => "biggles2" 
2.3.4 :011 > c.content='this is some content and its not too long'
 => "this is some content and its not too long" 
2.3.4 :012 > c.valid?
 => true 
2.3.4 :013 > c
 => #<Contact:0x000000055741a8 @name="biggles2", @validation_context=nil, @errors=#<ActiveModel::Errors:0x0000000554a948 @base=#<Contact:0x000000055741a8 ...>, @messages={}, @details={}>, @email="biggldy@boggldy.com", @content="this is some content and its not too long"> 
Owen
  • 361
  • 1
  • 5
  • 16
  • in new.html.erb, you're missing the code that displays the error messages. It looks something like @contact.errors.full_messages ..... – Ahmad Al-kheat Mar 12 '18 at 12:44
  • The book doesn't say anything about his code. the new.html.erb file is copy pasted directly from the tutorial page 266 chapter 19. Also same as github code https://github.com/RailsApps/learn-rails/blob/master/app/views/contacts/new.html.erb . Could there be another reason the error messages are not working? – Owen Mar 12 '18 at 12:50
  • check out this questions https://stackoverflow.com/questions/46344681/error-not-displaying-with-form-with , see how the asker has the errors part in his new.html.erb . – Ahmad Al-kheat Mar 12 '18 at 13:02
  • but in my case the error messages should already be rendered by the application layout and the _messages partial and therefore should not need to be present in the new.html.erb – Owen Mar 12 '18 at 13:10
  • 1
    flash is different than model errors. – Ahmad Al-kheat Mar 12 '18 at 14:36

0 Answers0