I have a very basic form, with some very basic validations (though I need to create a custom validation later... you'll probably see a question on that tomorrow. =P ), but I'm having trouble showing the user the validation errors.
Here's my main Sinatra file:
$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'sinatra'
require 'rubygems'
require 'datamapper'
require 'dm-core'
require 'dm-validations'
require 'lib/authorization'
DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/entries.db")
class Entry
include DataMapper::Resource
property :id, Serial
property :first_name, String, :required => true
property :last_name, String, :required => true
property :email, String, :required => true, :unique => true,
:format => :email_address, :messages => {
:presence => "You have to enter your email address",
:is_unique => "You've already entered",
:format => "That isn't a valid email address" }
property :created_at, DateTime
end
configure :development do
# create, upgrade, or migrate tables automatically
DataMapper.auto_upgrade!
end
helpers do
include Sinatra::Authorization
end
# Set UTF-8 for outgoing
before do
headers "Content-Type" => "text/html; charset=utf-8"
end
get '/' do
@title = "Enter to win a rad Timbuk2 bag!"
erb :welcome
end
post '/' do
@entry = Entry.new(:first_name => params[:first_name], :last_name => params[:last_name], :email => params[:email])
if @entry.save
redirect("/thanks")
else
@entry.errors.each do |e|
puts e
end
redirect('/')
end
end
get '/list' do
require_admin
@title = "List of Entries"
@entries = Entry.all(:order => [:created_at.desc])
erb :list
end
get '/thanks' do
erb :thanks
end
get '/delete/:id' do
require_admin
entry = Entry.get(params[:id])
unless entry.nil?
entry.destroy
end
redirect('/list')
end
So, if a user tries to submit an entry with only a first name, or only a last name, or nothing at all, I can see the errors in my console, but I can't figure out how to get them in the page displayed by my main handler.
I've tried adding a div:
<% unless @entry.errors.empty? %>
<div id="errors">
<% @entry.errors.each do |e| %>
<p><%= e %></p>
<% end %>
</div>
<% end %>
but I get: undefined method `errors' for nil:NilClass
What happens in your case is that the redirect will clear the errors again internally. You need to store them temporarily to have them available after the redirect. From Sinatra documentation on how to pass data on through redirects:
So in your case this would be
and
for your Sinatra file.
Your erb file would become
Can you try this :