Having Difficulty Accessing Validation Errors in Sinatra

Having difficulty accessing validation errors in Sinatra

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 %>

Ruby Sinatra validation returning errors to the view

From the documentation:

The return value of a route block determines at least the response body passed on to the HTTP client, or at least the next middleware in the Rack stack. Most commonly, this is a string

You're trying to pass an array instead of a string. The return types are (again, listed in the docs)

  • An Array with three elements: [status (Fixnum), headers (Hash), response body (responds to #each)]
  • An Array with two elements: [status (Fixnum), response body (responds to #each)]
  • An object that responds to #each and passes nothing but strings to the given block
  • A Fixnum representing the status code

If you posted up the code you'd written it'd be easier to show you what to do, but this is basically what's happening.


From additional code:

In the route, at the very end of it, try something like this:

get '/contact' do
# other code, then…

if @emails.errors

  unless @emails.errors?
haml :show_a_nice_view_to_the_user
else
output = @emails.errors.join("; ")
# log problems…

halt 500, output

    haml :error_template
end
end

# in the error_template (or the show_a_nice_view_to_the_user
# it's up to you if you show a special page or not)
- @errors.full_messages.each do |error|
%p= error

Sinatra PUT method not working?

That all looks correct. It looks like you either wrote the route string wrong, or it's being caught by another route before your put method. I was curious about this so I wrote up a quick Sinatra app that used a put method, and it does indeed work this way.

#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra'

get '/' do
<<-eos
<html>
<body>
<form action="/putsomething" method="post">
<input type="hidden" name="_method" value="put" />
<input type="submit">
</form>
</body>
</html>
eos
end

put '/putsomething' do
"You put something!"
end

Displaying Error Message with Sinatra

You can use the 'sinatra-flash' gem to display all kinds of errors/notices etc.

u = User.new
u.email = params[:email]
u.save
if u.save
redirect '/'
else
flash[:error] = "Format of the email was wrong."
redirect '/'
end

Then you need to say where you want the flash[:error] to be displayed. Normally I put this in the layout.haml or (erb) file right above where I yield in the content.

layout.haml:

- if flash[:error]
%p
= flash[:error]

Also, make sure you include the gem and enable sessions

require 'sinatra'
require 'sinatra/flash'

enable :sessions

You could also try the 'rack-flash' gem. There is a tutorial for using it at http://ididitmyway.heroku.com/past/2011/3/15/rack_flash_/

Methods to validate whether user is logged in aren't working for Sinatra Application.

Use find_by(id: session[:user_id]) instead of find(session[:user_id]).

find raises an error if a nil id is passed, or no matching record is found. find_by doesn't raise an error in either of these situations.

Since your code allows for the result of this query to be nil (the @current_user variable will be nil, and so will the return value of the current_user method) it seems this one change will solve your problem.

Determine source property of DataMapper validation errors

The errors object is an instance of DataMapper::Validations::ValidationErrors which has an on method that will return an array containing all the validation error messages for the property you pass as a parameter, or nil if there are no errors. (It looks like those docs don't actually match the implementation).

user = User.new username: 'joe', :age => 40

if user.save
#success!
else
puts "Username: #{user.username} #{user.errors.on(:username)}"
puts "Age: #{user.age} #{user.errors.on(:age)}"
end

produces (with suitable validations set up):

Username: joe ["Username must be between 4 and 20 characters long"]
Age: 40

How can I serialize DataMapper::Validations::ValidationErrors to_json in Sinatra?

So, as I was typing this up, the answer came to me (of course!). I've burned several hours trying to figure this out, and I hope this will save others the pain and frustration I've experienced.

To get the JSON I'm looking for, I just had to create a hash like this:

{ :errors => person.errors.to_h }.to_json

So, now my Sinatra route looks like this:

get '/person' do
person = Person.new :first_name => 'Dave'
if person.save
person.to_json
else
{ :errors => person.errors.to_h }.to_json
end
end

Hope this helps others looking to solve this problem.



Related Topics



Leave a reply



Submit