How Do You Roll With Sinatra?

717 views
Skip to first unread message

DAZ

unread,
Aug 12, 2012, 3:53:30 PM8/12/12
to sina...@googlegroups.com
Hi fellow Sinatra users!

I'm researching an article for RubySource highlighting the flexibility that Sinatra offers - ie you can literally choose how to structure your projects.

I was hoping some of you would be able to help me out by telling me about any patterns that you use when using Sinatra? In particular:
  • Do you have a set folder structure or coding patterns?
  • Do you tend to use classic or modular style?
  • Do you use any bootstrap code?
  • Do you ever use inline-views?
  • Anything else?
Thanks so much in advance!

DAZ

davesag

unread,
Aug 12, 2012, 9:13:26 PM8/12/12
to sina...@googlegroups.com
I always use the modular style, even for simple projects, as most simple projects tend to become more complex anyway.

I like to split out my helpers early and these days have a bunch of reusable helpers. Also I like to code up my views using Javascript / jQuery and use AJAX to talk to the API served up by Sinatra rather than using Sinatra to populate local variables to be rendered via HAML. It's more flexible that way I've found and forces me to think about my server side app as a set of APIs earlier.

I use ActiveRecord for my database layer (which seems a bit old-school now I know, but it works and is tried and tested)

I use bundler for Gem management and TestUnit for unit testing.  I run in test and development environments on my Mac at home and push to Heroku for production level user acceptance testing; and typically clients then decide where they want their final code to be hosted and on what Db.  I remain as DB agnostic as possible using ActiveRecord and test and develop using SQLite on my Mac and whatever Heroku wants on Heroku. I store uploads locally on my Mac during testing an development, and on Amazon when pushed to Heroku. I keep source code on GitHub.

I tend to spec out my projects, including Object Graphs, Interaction diagrams, and Wireframes, using OmniGraffle before writing any code and get sign-off from the client on that, but at the same time I like to stay flexible to client's changing needs.  I use RedMine to manage issues and tickets during and after the development process rather than GitHub as for some reason many of my clients find that their IT departments block access to GitHub.

My folder structure tends to always look like
app/
  config/
  content/
    pages/
    uploads/  (for local testing only else Amazon)
  db/
    migrate/
  lib/
    sinatra/
  models/
  public/
  test/
  views/

In my views folder I have a page called page.haml which wraps page content (extracted from haml and markdown pages with header data) that lives in the content folder.  I have a default route in a helper that looks for any gets and matches them to the names of files in the content folder and extracts the page data which is then wrapped in this page.haml before being displayed.  This means my page level information is very simple.

This works in a similar manner to the Nesta CMS actually which is also built on Sinatra.

I don't use inline views as I like to keep concerns separate.

I'm a huge fan of HAML and SASS though I must say, and overall a huge fan of Sinatra. It's really become my Web App construction kit of choice.

Hope that's some help. Alas I don't have any public examples of my code as the work I do is wrapped up in clients' confidentiality agreements.

Dave

Jason Rogers

unread,
Aug 13, 2012, 12:26:33 AM8/13/12
to sina...@googlegroups.com
I typically have a folder structure based on the size of the project.

Small:
  models/ (if necessary)
  public/ (css, js, images)
  views/ (haml, if necessary)
  app.rb (contains all routes, whether modular or classic)
  helpers.rb

More than Small:
  public/
  app/
    helpers/
    models/
    routes/
    views/
  lib/
    config/
    extensions/
    jars/ (if running in JRuby)
  app.rb (loads routes and other essentials)

As for Classic vs. Modular, it depends on the nature of the routes. For instance, if I'm going to have resources split out under separate paths (eg. "/admin", "/api", etc.) I will use a modular approach and map the individual modules in Rack under their path name. Other than that, I tend to use Classic.

The only bootstrapping I tend to do is to load configurations/settings.

I never use inline views.

I tend to do TDD with RSpec (not real BDD).

For an SQL OM, I will use Sequel over ActiveRecord any day, and twice on Sundays!

For a NoSQL backend, I tend to use MongoDB (and MongoMapper when I need an ORM'ed set of models).

I like jQuery on the front-end, with KnockOut.js. I like having one-page apps.

I tend to write my Sinatra apps as WebService-centric applications, but when I need to render views I usually choose HAML.
--
You received this message because you are subscribed to the Google Groups "sinatrarb" group.
To view this discussion on the web visit https://groups.google.com/d/msg/sinatrarb/-/Y87Zr91buY8J.
To post to this group, send email to sina...@googlegroups.com.
To unsubscribe from this group, send email to sinatrarb+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/sinatrarb?hl=en.


--

--
Jason Rogers

Randy Fischer

unread,
Aug 13, 2012, 4:01:26 AM8/13/12
to sina...@googlegroups.com
In the anything else category, I immediately turn off development mode, and make sure I get logging and exception handling working up front - it's too painful leaving it to the end of the development (and sad to say, I've seen many that never actually bother getting error handling set up sensibly. A stack trace is not a valid user interface, say I).

So..

configure do
  disable :logging
  disable :dump_errors
  set :environment,  :production
  set :raise_errors, false

  use Rack::CommonLogger, Logger.new(...)
  ...
end

I usually set up some minimalist shim for error handling, where I map my class's exceptions to HTTP errors:

  class HttpError < StandardError;
    def client_message
      "#{status_code} #{status_text} - #{message.chomp('.')}."
    end
  end

  class Http400Error < HttpError;  end

  class Http400 < Http400Error
    def status_code; 400; end
    def status_text; "Bad Request"; end
  end
  class Http401 < Http400Error
    def status_code; 401; end
    def status_text; "Unauthorized"; end
  end
  ...
  class Http415 < Http400Error                                                                                                                                      
    def status_code; 415; end                                                                                                                                       
    def status_text; "Unsupported Media Type"; end                                                                                                                  
  end      

and so on ... more HTTP boiler plate

For my application, the shim maps the application errors to HTTP codes - I might have:

  class BadXmlDocument      < Http415; end                                                                                                                          

Which might be raised in an application

raise BadXmlDocument, "The submitted XML file #{filename} had too many errors: " + document.err

All of the application exceptions can be caught by a generic error block (with, yes,
logged backtraces for the unexpected)

error do
  e = @env['sinatra.error']

  request.body.rewind if request.body.respond_to?('rewind')  # phusion work-around

  if e.is_a? HttpError
    Logger.err e.client_message, @env
    [ halt e.status_code, { 'Content-Type' => 'text/plain' }, e.client_message ]   
  else
    Logger.err "Internal Service Error - #{e.message}", @env
    e.backtrace.each { |line| Logger.err line, @env }
    [ halt 500, { 'Content-Type' => 'text/plain' }, "Internal Service Error.\n" ]
  end
end


This works well enough for me that I use it for even simple web interface.

-Randy Fischer






de Herdt Arne

unread,
Aug 13, 2012, 2:24:12 AM8/13/12
to sina...@googlegroups.com

Hey,

 

Nice topic to see how people use Sinatra as well.

I usually stick to the following structure:

 

-          Root

o   Models

§  Init.rb

§  Mode files

o   Routes

§  Init.rb

§  Route files

o   Views

o   Public

o   Application.rb

o   Config.ru

 

The config.ru file set’s up the variables such as the environment and root path for the application.

Application.rb defines the “server application” and all helper methods etc, no routes. The file then relies on require_relative to include the init files from models and routes.

All other folders should be self-explaining.

 

Arne De Herdt

Software Engineer

 

ProSiebenSat.1 Games GmbH

Ein Unternehmen der / A company of ProSiebenSat.1 Media AG

 

Medienallee 19

D-85774 Unterföhring

Tel. +49 [89] 9507-8808

Fax +49 [89] 9507-98896

 

Arne.d...@ProSiebenSat1Games.com

 

Geschäftsführer: Markus Büchtmann, Andreas Heyden, Achim Kaspers

Firmensitz / Company Residence: München / Munich, Germany

HRB 119657 AG München / Local Court in Munich, Germany

Alper Akgün

unread,
Aug 12, 2012, 4:06:38 PM8/12/12
to sina...@googlegroups.com
we have several "enterprise" web sinatra projects from 20K to 200K lines of code.
  • rubygems gem-like structure folder structure (lib,test/spec/, public)  and padrino/rails -like  app/(model view controller) structure
  • modular style
  • no inline-views but template(&block) views or files
  • sequel and datamapper orms for mysql
  • twitter bootstrap and lots of code generation



DAZ

--

DAZ

unread,
Aug 13, 2012, 8:26:25 AM8/13/12
to sina...@googlegroups.com
Wow! Some really interesting replies so far.

Very interesting to see the different file structures and that everybody who has replied so far seems to be using Sinatra for some quite big projects. Do you like the fact that Sinatra lets you set things up your way? Why not just use Rails?

Completely different to me - I love building things in just one file using the classic style and inline views ... but this is generally just for tinkering and playing around with things. I love the immediacy that Sinatra gives me to just build something really quickly. I love inline views because I can just stub some things out really quickly in the same file. 

What I love more is that Sinatra let's both of these type of developing happen!

cheers,

DAZ

Jason Rogers

unread,
Aug 13, 2012, 10:29:14 AM8/13/12
to sina...@googlegroups.com
Yeah, I love the flexibility of Sinatra. I don't agree with a lot of Rails' opinions (especially ActiveRecord opinions); I also don't tend to use Rails' view helpers.
--
You received this message because you are subscribed to the Google Groups "sinatrarb" group.
To view this discussion on the web visit https://groups.google.com/d/msg/sinatrarb/-/q43II51Zm_4J.

To post to this group, send email to sina...@googlegroups.com.
To unsubscribe from this group, send email to sinatrarb+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/sinatrarb?hl=en.


--

--
Jason Rogers

Zachary Scott

unread,
Aug 13, 2012, 1:01:30 PM8/13/12
to sina...@googlegroups.com
Without turning this thread into "what i hate about rails", I think
Jason is spot on for app organization.

It depends on the app and/or team size

Angel Java Lopez

unread,
Aug 13, 2012, 1:09:32 PM8/13/12
to sina...@googlegroups.com
I'm a newbie, but I would like to ask, regarding "lots of code generation"

- What kind of code is generated?
- Tool you are using?

Alper Akgün

unread,
Aug 13, 2012, 4:35:20 PM8/13/12
to sina...@googlegroups.com

Angel, the code generation tool is used only in-house currently; but i plan to release it  as open source soon;  

Everybody out there using sinatra - What would you like to see most in a meta programming /code generation framework and initial repository?

I’m doing a (free) meta programming, code generation framework (just a hobby, won’t be big and professional) for sinatra. This has been brewing
since november 2010, and is starting to get ready. I’d like any feedback on  things people like/dislike on top of sinatra/(or rails), as my framework resembles/exceeds rails meta programming somewhat and repeats rack middleware architecture on the other hand;

We’ve currently developed a dozen projects and things seem to work.  This implies that I’ll get something practical to release within a few months, and  I’d like to know what features most people would want in a tool for the laziest programmers. Any suggestions  are welcome, but I won’t promise I’ll implement them :-)

PS. Yes – it works with ruby 1.9.x and later, provides mvc and variations, excels at datamapper/sequel,mysql/elasticsearch/redis, jquery/ui, sass/css, erb/slim, ace/emacs, cloud provisioning/fog(used for aws/rackspace) similar to chef/puppet, tdd (but not bdd). currently generates and remixes codes for; cms, blog, seo/opengraph support, erp (order, invoice, quotes,....), doc management, commenting, social integration, auth*, adsense to name a few.

davesag

unread,
Aug 13, 2012, 7:36:17 PM8/13/12
to sina...@googlegroups.com
Ak

In the email the spacing collapsed, making my folder structure look stupid.

Here it is again for the record 

app/
-  config/
-  content/
--    pages/ (usually haml files with some meta-data at the top)
--    uploads/  (for local testing only else Amazon)
-  db/
--    migrate/
-  lib/
--    sinatra/ (helpers)
-  models/
-  public/
-  test/
-  views/

Ed Drain

unread,
Aug 15, 2012, 9:08:49 AM8/15/12
to sina...@googlegroups.com
Why not just use rails?  Rails is like bringing a destroyer to a pirate/hostage situation when you really need a Special Forces or Seal team.  Large applications?  Large apps is kind of misleading as it really depends on the break down of how it is organized.  Large and monolithic is very different than large and modular. Writing software as a service encourages separation of concerns.  Sinatra seems ideal for such separation.  

--
You received this message because you are subscribed to the Google Groups "sinatrarb" group.
To view this discussion on the web visit https://groups.google.com/d/msg/sinatrarb/-/q43II51Zm_4J.

DAZ

unread,
Aug 17, 2012, 12:10:24 PM8/17/12
to sina...@googlegroups.com
Thanks again for the interesting comments here.

I definitely don't want this to be anything about hating Rails ... it's just that Sinatra is so often trumpeted as something to be used for 'small' projects, there is a feeling amongst some people that only Rails will do if you are working on a 'big' project. Interesting to see the different folder structures that people use and to hear that you like the control Sinatra gives you over how things work.

Do you think Sinatra gets the balance right between making access to Rack and the HTTP layer easy, but giving you control or do you think it could do with more helpers ... or is that what gems are for?

cheers,

DAZ

On Sunday, August 12, 2012 8:53:30 PM UTC+1, DAZ wrote:

Jason Rogers

unread,
Aug 17, 2012, 12:20:44 PM8/17/12
to sina...@googlegroups.com
I'd say that's what gems are for. As you can see, folks use Sinatra differently. One of the great benefits of Sinatra is its lack of opinions.

--
Jason Rogers


--
You received this message because you are subscribed to the Google Groups "sinatrarb" group.
To view this discussion on the web visit https://groups.google.com/d/msg/sinatrarb/-/bBqTfgmGa40J.

Josh Cheek

unread,
Aug 19, 2012, 2:09:50 AM8/19/12
to sina...@googlegroups.com
On Sun, Aug 12, 2012 at 2:53 PM, DAZ <daz...@gmail.com> wrote:
Hi fellow Sinatra users!

I'm researching an article for RubySource highlighting the flexibility that Sinatra offers - ie you can literally choose how to structure your projects.

I was hoping some of you would be able to help me out by telling me about any patterns that you use when using Sinatra? In particular:
  • Do you have a set folder structure or coding patterns?

As an app gets larger, I tend to move it more towards a Rails-like structure. For smaller things, I fit the solution to the problem. E.g. this one-file app https://github.com/JoshCheek/legit-quotes/blob/4a7fab9275ac989105357f2babb4ef84e3c94b2b/lib/quote_app.rb
  • Do you tend to use classic or modular style?

I go back and forth. For a larger app, go modular. When showing off, go classic.
  • Do you use any bootstrap code?
No
  • Do you ever use inline-views?
Yes
  • Anything else?

For really small things, I just build right on top of Rack, e.g. https://github.com/JoshCheek/stop-committing-in-the-future/blob/5de4f36a8996d1b7d29c5012d6de68b33978c35b/lib/time_server.rb

For something big, I'd either use Rails or Padrino (built on Sinatra). There is a project some colleagues of mine are working on that is getting quite large and is built on Sinatra, but not released yet so I can't link to it. It's working well for them AFAIK, but for larger things, I tend to want a bit more hand-holding than Sinatra provides.

You can also mount these kinds of apps in Rails projects, which I think is incredibly cool. If you're going to build a Rails engine, at least consider doing this before you make up your mind.

-Josh

DAZ

unread,
Jan 23, 2013, 3:12:54 AM1/23/13
to sina...@googlegroups.com
Hi guys,

It's been a while, but the article has now been published. Thanks a lot for your contributions!

DAZ

On Sunday, August 12, 2012 8:53:30 PM UTC+1, DAZ wrote:

Jason Rogers

unread,
Jan 23, 2013, 10:40:31 AM1/23/13
to sina...@googlegroups.com
Good read. Thanks for putting it together.


--
Jason Rogers


--
 
 

Reply all
Reply to author
Forward
0 new messages