user4992261
user4992261

Reputation: 31

user validations & displaying an error message in a view

This is for an app that uses Sinatra and ActiveRecord. I'm trying to get an error message to display on my view file (_form.erb), but Sinatra just displays the "I don't know this ditty" message and doesn't display the actual error message on the page.

This is for a form where a user is supposed to input a first name, last name, and birthdate. "validates_presence_of :birthdate, :first_name, :last_name" is supposed to check that the fields aren't blank but I'm not sure if the code I have actually does that so that's why the error message isn't showing. In particular, the part of the post route below that has:

if params[:birthdate].include?("-")
        birthdate = params[:birthdate]
    else
        birthdate = Date.strptime(params[:birthdate], "%m%d%Y")
end

assumes that there always is input so Sinatra says "ArgumentError: invalid date" if you leave the birthdate field blank and won't ever show an error message. I'm not sure how to get Sinatra to stop giving that error for the birthdate field and show an error message on the page, but the error message won't display if I input a birthdate and leave the name fields blank either.

This is the relevant route in my people_controller.rb file:

#create a new person
#if-else clause accounts for date input with dashes and without dashes (string input)
post "/people" do
    if params[:birthdate].include?("-")
        birthdate = params[:birthdate]
    else
        birthdate = Date.strptime(params[:birthdate], "%m%d%Y")
    end

    @person = Person.new(first_name: params[:first_name], last_name: params[:last_name], birthdate: birthdate)
    if @person.valid?
        @person.save
        redirect "/people/#{@person.id}"
    else
        @error = "The data you entered isn't valid"
        erb :"/people/new"
    end
end

This is my people/new.erb file:

<h1>Create a Person</h1>
<%= erb :"/people/_form" %>

This is my people/_form.erb file:

<% if [email protected]? %>
  <p class="errors">
    <%= "#{@errors}" %>
  </p>
<% end %>
<form action="<%= people_form_action(@person) %>" method="post" id="<%= people_form_id(@person) %>" class="<%= people_form_class(@person) %>">
  <input type="hidden" name="_method" value="<%= people_form_method(@person) %>" />
  <div>
    <label for="first_name">First Name:</label>
    <input type="text" name="first_name" value="<%= @person.first_name %>" />
  </div>

  <div>
    <label for="last_name">Last Name:</label>  
    <input type="text" name="last_name" value="<%= @person.last_name %>" />
  </div>

  <div>
    <label for="birthdate">Birthdate:</label>
    <input name="birthdate" type="date" value="<%= @person.birthdate %>" />
  </div>

  <div>
    <input type="submit" />
  </div>
</form>

This is my Person class:

class Person < ActiveRecord::Base

    validates_presence_of :birthdate, :first_name, :last_name

    def self.get_birth_path_num(birthdate)

        number = birthdate[0].to_i + birthdate[1].to_i + birthdate[2].to_i + birthdate[3].to_i + birthdate[4].to_i + birthdate[5].to_i + birthdate[6].to_i + birthdate[7].to_i
        number = number.to_s
        number = number[0].to_i + number[1].to_i

        if(number > 9)
            number = number.to_s
            number = number[0].to_i + number[1].to_i
        end

        return number
    end


    def self.get_message(number)
        case(number)
            when(1)
                message = "One is the leader. The number one indicates the ability to stand alone, and is a strong vibration. Ruled by the Sun."
            when(2)
                message = "This is the mediator and peace-lover. The number two indicates the desire for harmony. It is a gentle, considerate, and sensitive vibration. Ruled by the Moon."
            when(3)
                message = "Number Three is a sociable, friendly, and outgoing vibration. Kind, positive, and optimistic, Three's enjoy life and have a good sense of humor. Ruled by Jupiter."
            when(4)
                message = "Your numerology number is 4. This is the worker. Practical, with a love of detail, Fours are trustworthy, hard-working, and helpful. Ruled by Uranus."
            when(5)
                message = "This is the freedom lover. The number five is an intellectual vibration. These are 'idea' people with a love of variety and the ability to adapt to most situations. Ruled by Mercury."
            when(6)
                message = "This is the peace lover. The number six is a loving, stable, and harmonious vibration. Ruled by Venus."
            when(7)
                message = "This is the deep thinker. The number seven is a spiritual vibration. These people are not very attached to material things, are introspective, and generally quiet. Ruled by Neptune."
            when(8)
                message = "This is the manager. Number Eight is a strong, successful, and material vibration. Ruled by Saturn."
            when(9)
                message = "This is the teacher. Number Nine is a tolerant, somewhat impractical, and sympathetic vibration. Ruled by Mars."
        end
    end

    #method to check if a user enters a valid birthdate
    def self.valid_birthdate(input)
        if(input.length==8 && input.match(/^[0-9]+[0-9]$/))
            return true
        else
            return false
        end
    end

end

Upvotes: 0

Views: 1569

Answers (1)

ian
ian

Reputation: 12251

I'm not sure how to get Sinatra to stop giving that error for the birthdate field and show an error message on the page

If you want an error page for invalid input, then use the error handler or halt:

if params["birthdate"].nil? || params["birthdate"].empty?
  halt 404, erb(:my_custom_error_page_for_invalid_stuff)
end

or

error InvalidBirthdate do
  halt 404, erb(:my_custom_error_page_for_invalid_stuff)
end

if params["birthdate"].nil? || params["birthdate"].empty?
  raise InvalidBirthdate, "Birthdate was empty!"
end

If you use the error handler you get access to the env['sinatra.error'].message which you can use in the template if you like.


Edit:

I'm actually trying to get the error message to display on the same page without creating another page with the error message though

Ok, so there's a couple of ways to do this. First thing to say is that the response should never be sent to the server at all, there are HTML5 validations you can use and perhaps overlay javascript validations too. That doesn't mean you shouldn't check on the server too, there are clients not using javascript, malicious clients etc.

So, one way to do this is to have a flash or a conditional in the template. Here's an simplistic flash message (using a flash library would be better):

helpers do
  def flash warning
    %Q!<span class="flash warning">#{warning}</span>!
  end
end

# in the route
if params["birthdate"].nil? || params["birthdate"].empty?
  halt 404, haml(:_form, :locals => {warning: "Fill in your birthdate!"})
end

#_form.haml   # I never use ERB and can't remember conditional syntax for it, sorry
- if warning
  = flash warning 
-# rest of form follows… try to put in their initial responses too :)

Alternatively you could use AJAX to send the form and never take them away from the page, or you could put the actual form part in a partial and include that in _form.erb and _my_form_error_page.erb and serve whichever one suits.

Upvotes: 1

Related Questions