rubysinatrahamlshotgun

Why doesn't the sinatra-redirect-with-flash gem work with shotgun?


I want to show flash messages using sinatra-redirect-with-flash gem.

Here's my ruby code:

require 'sinatra'
require 'sinatra/base'
require 'sinatra/flash'
require 'sinatra/redirect_with_flash'
require 'data_mapper'
require 'haml'
require 'builder'

# ...

class App < Sinatra::Base
  enable :sessions
  register Sinatra::Flash
  helpers Sinatra::RedirectWithFlash
  use Rack::MethodOverride

  get '/' do
    @notes = Note.all :order => :id.desc
    @title = 'All TODOs'
    if @notes.empty?
      flash.now[:error] = 'No TODOs found. Add your first below.'
    end
    haml :home
  end

  post '/' do
    n = Note.new
    n.content = params[:content]
    n.created_at = Time.now
    n.updated_at = Time.now
    if n.save
      redirect '/', :notice => 'TODO saved successfully.'
    else
      redirect '/', :error => 'Failed to save TODO.'
    end
  end

  # ...

end

And views/layout.haml is:

!!! 5
%html{:lang => "en"}
  %head
    %meta{:charset => "utf8"}
  %body
    %header
      %hgroup
        %h1
          %a{:href => "/"}= SITE_TITLE
        %h2= SITE_DESCRIPTION
    #main 
      =styled_flash
      =yield 

After adding a TODO successfully, I expected to see the flash message 'TODO saved successfully.' on the home page. But no flash messages are shown after redirection when I run my app using shotgun. Flash messages are shown well when I run ruby app.rb or rackup.

How can I solve this problem?

Another problem is also happening when I run the app using shotgun. In get '/' method, if I use flash[:error] instead of flash.now[:error], the flash message doesn't show up on the page.

I am shadowning this tutorial, but I made some differences:

You can browse whole codes here.

Thanks for any answers/comments.


Solution

  • The shotgun gem reloads Sinatra after every request. The README says:

    Each time a request is received, it forks, loads the application in the child process, processes the request, and exits the child process. The result is clean, application-wide reloading of all source files and templates on each request.

    As a result, you will need some sort of mechanism to preserve state between requests that doesn't rely on data stored in each child process.