Having difficulty accessing validation errors in S

2019-02-15 13:55发布

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

2条回答
▲ chillily
2楼-- · 2019-02-15 14:27

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:

Or use a session:

  enable :session

  get '/foo' do
    session[:secret] = 'foo'
    redirect to('/bar')
  end

  get '/bar' do
    session[:secret]
  end

So in your case this would be

get '/' do
    @title = "Enter to win a rad Timbuk2 bag!"
    @errors = session[:errors]
    erb :welcome
end

and

if @entry.save
    redirect("/thanks")
else
    session[:errors] = @entry.errors.values.map{|e| e.to_s}
    redirect('/')
end

for your Sinatra file.

Your erb file would become

<% if @errors %>
<div id="errors">
    <% @errors.each do |e| %>
       <p><%= e %></p>
    <% end %>
</div>
<% end %>
查看更多
祖国的老花朵
3楼-- · 2019-02-15 14:36

Can you try this :

post '/' do
  @entry = Entry.new(:first_name => params[:first_name], :last_name => params[:last_name], :email => params[:email])

  if @entry.save
    redirect("/thanks")
  else
    @title = "Enter to win a rad Timbuk2 bag!"
    erb: welcome
  end
end
查看更多
登录 后发表回答