Over a million developers have joined DZone.

Building a Data Driven App with Sinatra

· Web Dev Zone

Building simple web applications with Sinatra is quick, and, well, simple. In this article we are going to build a simple Sinatra app that connects to a database to store blog posts. Not only that, but we are going to build it with deployment to Heroku in mind. Let’s get started…

First, create a new folder called blog, and then add a new file called main.rb. One of the nice things about Sinatra is, we can work locally using a Sqlite database. But when we deploy, we can utilise Heroku’s Postgresql shared database.

To get started, in main.rb require the gems that we will be needing:

require 'sinatra'
require 'data_mapper'
require 'dm-migrations'
require 'dm-timestamps'

Then we’ll add our database connection using Data Mapper:

#database connection
DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/development.db")

Next, we’ll create a method for the home page of our app:

get '/' do
    erb :index
end

Now create a folder called views and add 2 files:

  • index.erb (the home page)
  • layout.erb

A really nice feature with Sinatra is that layout.erb will be detected and used as exactly that – the layout for all the pages in the app. Come up with whatever design you would like to use, and add it as normal html markup in layout.erb.

There are a couple of Ruby calls that we will add to layout.erb. In the place in your layout you intend for the main page content to appear, add this:

<div id="content-wrapper">
    <div id="content">
        <%= yield %>
    </div>
</div>

You should also add a folder called public in the root. This is where you add any stylesheets and images.

If you want to have repeated sections in your layout that appears across all pages, you can use partials. Create a new folder inside your views folder called partials. Then in your layout you can do this:

<div id="sidebar-wrapper">
    <div id="sidebar">
        <%= erb :'partials/twitter' %>
    </div>
</div>

Here, you see I have added a partial to display my Twitter feed.

To add other static pages it’s as simple as creating a method in main.rb:

get '/about' do
    erb: about
end

Data Please…

To begin working with data we must first create a model. We are using the DataMapper gem in this app. Add this after the database connection:

class Post
    include DataMapper::Resource
    
    property :id, Serial
    property :title, String
    property :content, Text
    property :created_at, DateTime
end

DataMapper.finalize
DataMapper.auto_upgrade!

To run our app to see how it looks, open terminal, cd into your blog folder and then do:

ruby main.rb

Sinatra wil start up the web server, and you’ll be told that your app is running on http://localhost:4567. When you run the command, this line: DataMapper.auto_upgrade! will ensure that your model runs and creates a table in accordance with the model specified (you may have to re-start the server):

The database

Now we can create a view called posts in the views folder and add the following:

<h2>Posts</h2>
<% unless @posts.empty? %>
    <% @posts.each do |post| %>
        <p>
            <a href="/view/<%= post.id %>"><%= post.title %></a> -
<em><%= post.created_at.strftime("%e %b %Y %H:%m:%S%p") %></em>
        </p>
    <% end %>
<% else %>
    <p>No posts available at the moment.</p>
<% end %>

This will list all of our posts. Next, we’ll create another view called view_post.erb The purpose of this one is to display an individual post when clicked on from our list above.

First, we’ll need a method in main.rb to handle it:

 get '/view/:id' do
    @post = Post.get(params[:id])
    erb :view_post
end

You can see here that we are retrieving the id of the post from the url parameter, and then using DataMapper to retrieve the post.

Add some posts manually to your database for now.

Now for view_post.erb:

<h3><%=@post.title %></h3>
<p><em><%= @post.created_at.strftime("%e %b %Y %H:%m:%S%p") %></em></p>
<%=@post.content %>

Since the query we send into the database should only retrieve one record, there is no need for a loop this time. We can call our instance variable (@post) directly to retirve the data returned.

The Gemfile

To prepare to deploy our app to Heroku, we will need a Gemfile. In the root of the app, create a new file called Gemfile. Just that – no file extension, and an uppercase G.

Add this:

source :rubygems
gem 'sinatra'
gem 'data_mapper'
gem 'dm-migrations'
gem 'dm-timestamps'
gem 'dm-postgres-adapter', :group => :production
gem 'dm-sqlite-adapter', :group => :development
group :production do
  gem 'pg', '0.14.1'
end

 

There is an important bit of setting up here. We have identifed that we want to use Sqlite for development, but Postresql for production. That’s because Heroku doesn’t support Sqlite.

Finally…

You now have a basic working blog application. Next, I’ll take you though the process of deploying it to Heroku.

 

 

 

 

 

 

 

 

 

 

 

 

 

Topics:

Published at DZone with permission of Andy Hawthorne, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}