0

When I enter data into a form that I know should fail, it doesn't. As per my model below, I require the data to be any combination of a-z, A-Z, 0-9 and whitespace, and when I stuff the form with garbage like )(&^%^&(*&%^&** or even submit an empty field, I would expect there to be errors. In this case, there isn't.

Here's the salient part of the model:

class Numerology
  include ActiveModel::Model

  attr_accessor  :phrase

  VALID_PHRASE_REGEX = /\A[a-zA-Z0-9\s]+\z/

  validates :phrase, presence: true, length: { minimum: 1 },
            format: { with: VALID_PHRASE_REGEX }

Here's the controller...what I want it to do is go back to the index (the page with the form on it) with whatever errors are generated when I supply wrong input on the form. Not sure I'm going about it the right way here, but I think this might be a secondary question since I don't seem to get ANY errors generated at all (so of course @numerology.errors.any? would be false).

class NumerologiesController < ApplicationController
  before_filter :authenticate_user!
  respond_to :html

  def index
    @numerology = Numerology.new
  end

  def create
    @numerology = Numerology.new(params[:numerology])
    if @numerology.errors.any?
      render :index
    else
      @numresults = Numerology.analysis(params[:numerology][:phrase])
    end
  end

end

And then finally, here are the views, first the index and then the create:

The Index page:

<div class="center jumbotron">
  <h1>Numerology Analysis Module</h1>

  <br>
  <%= bootstrap_form_for(@numerology, layout: :horizontal, label_col: "col-sm-4", control_col: "col-sm-6") do |f| %>

    <p> Enter word or phrase to be analyzed in the field below (Required).</p>

    <%= @numerology.errors.full_messages.each do |message| %>
      <li><%= message %></li>
    <% end %>
    <%= f.text_field :phrase, label: "Word or Phrase: " %>

    <br><br>

    <%= f.submit "Perform Numerological Analysis" %>
  <% end %>
  <br><br>
  <%= image_tag("SMILE.jpg", alt: "Smiley Face") %>
</div>

The Create page:

<div class="center jumbotron">
  <h1>Numerological Analysis Report</h1>
  <div class="numreport">
    <table class="numtable">
      <% @numresults.each do |line| %>
        <% if !line.nil? %>
          <tr>
            <td><%= "#{line}" %></td>
          </tr>
        <% end %>
      <% end -%>
    </table>
  </div>
  <%= link_to "Perform Another Numerological Analysis - Click Here",   numerologies_path %>
  <br><br><br>
  <%= image_tag("SMILE.jpg", alt: "Smiley Face") %>
</div>

So,does anyone see what I'm doing wrong here? Suggest other things to try? Thanks!

  • Nothing leaps out as obvious. I recommend trying this: 1) runs `rails console` 2) `n = Numerology.new(:phrase => ")(&^%^&(*&%^&**")` 3) `n.valid?` 4) `puts n.errors.inspect` 5) copy the output and edit your question and enter it... (unless the error becomes obvious to you with doing that). (Note: the turn-around is quicker in the rails console... plus you can isolate whether the validation is *actually working* vs *something is wrong in how the errors are being returned by the controller*) – Taryn East Jul 06 '16 at 03:19
  • 1
    Turns out the solution was that I wasn't calling valid? or invalid? anywhere, and once I did it all started to work. Thanks for your response and for pointing out the use of the console -- I will keep that in mind going forward. – David Herring Jul 06 '16 at 20:26

1 Answers1

0

You need to either call valid? or invalid? in order to populate the errors list.

http://api.rubyonrails.org/classes/ActiveModel/Validations.html#method-i-valid-3F

valid?(context = nil)

Runs all the specified validations and returns true if no errors were added otherwise false.

  def create
    @numerology = Numerology.new(params[:numerology])
    if @numerology.invalid?
      render :index
    else
      @numresults = Numerology.analysis(params[:numerology][:phrase])
    end
  end
Vadim
  • 17,897
  • 4
  • 38
  • 62
  • Success! Calling, in this case, invalid? was the magic bullet. Thanks for including the link to the doc page. Interestingly I had read that page in all my reading and googling, but for some reason it just didn't "click" in my mind what it was telling me (whereas in retrospect now it's obvious). Thank you for your help! – David Herring Jul 06 '16 at 20:23
  • 1
    Cool, great you found a solution. I didn't spot that you only had `new` and not `create/update` which are the usual ones (create/update will also call `valid?`). I did think I should say: it's generally a good ruby practice to use positives rather than negatives as the human brain has more difficulty figuring out negatives. So in this case I'd say `if @numerology.valid? (do_positives_stuff) else render :index` instead of the way around that you have it now... Otherwise, great work :) – Taryn East Jul 07 '16 at 00:05