jahrichie
jahrichie

Reputation: 1235

Ruby Sinatra validation returning errors to the view

Rails dev new to sinatra...I'm trying to do some simple validations. When I try:

validates_presence_of :email, message: "Email cannot be blank."

   @emails.errors.each do |e|
      puts e
    end 

Sinatra returns

[: errorI"^Rack::Lint::LintError: Body yielded non-string value [:email, ["Email cannot be blank."]

How can I extract the error messages from that array, and any further validations I apply to this table.

I've tried puts e.first and few other options and i'm getting no where. Should i do this differently?

Thanks in advance!

# app.rb
require "sinatra"
require "Clipboard"
require "sinatra/activerecord"
require 'pony'

#basic auth
use Rack::Auth::Basic, "Enter Demo password." do |username, password|
  [username, password] == ['censor', 'censor']
end


#options
set :port, 3000

# configure :development do
  set :database, "sqlite3:///exceptDev.db"
# end

#end options


######################
####    MODELS      #
######################

class Emails < ActiveRecord::Base
  #validate fields  
  validates_presence_of :email, message: "Email cannot be blank."
end



######################
####    ROUTES       #
######################

get '/' do
  erb :index
end


get '/contact' do
  #create email record
  @fullname = params[:name].split
  @emails = Emails.create(first_name: @fullname.first, 
                          email: params[:email], 
                          last_name: @fullname.last,
                          msg: params[:msg],
                          postcards: params[:postcards],
                          stickers: params[:stickers]
                          )

  if @emails.save 
    redirect "/", notice: "HYFR!"
  else
    redirect "", errors: "wsdfasdf"
    # @emails.errors.each do |e|
    #   puts e
    # end #errors block
  end #if save
end #contact action

Upvotes: 3

Views: 5666

Answers (1)

ian
ian

Reputation: 12251

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

Upvotes: 3

Related Questions