Continuing on with the Sinatra app we started in part one, we’ll now add some more pages and connect to a database.
Let’s begin by adding more pages. Sinatra makes that easy. All we need to do is add another action and create the associated ERB template. Like this:
get '/about' do erb :about end
Then, in the
views folder, create a file called:
about.erb and add whatever content you would like. You could use the same procedure to create other static pages, too.
Before we move on, let’s add some more functionality. What if we wanted to write our static pages using Markdown?
First, we need a gem to help us. I’m going to use rdiscount. There are others, so feel free to experiment.
Add it to your gem file:
bundle from the command line (make sure you have moved into your project folder).
Next, you can create a file called
about.md in your
views folder. We’ll need to change the action in
get '/about' do markdown :"pages/about", :layout_engine => :erb end
We are asking for our file to be transformed from Markdown into HTML. And, we are specifying that we want to use the layout file that is already set up.
Remember that if you add a file called
layout.erb in your views folder, Sinatra will automatically use it. You could also do something like this:
get '/about' do erb :about, :layout => :post end
That will use a layout file called
post.erb assuming it exists.
Back to our Markdown implementation. You have no more to do now, aside from writing your content. Your Markdown formatted content will be handled automagically.
Let’s assume that we are going to create a blog. That means we’ll need a database of some kind. That also means we have to think about the platform the site will run on.
Sinatra runs on rack, a standard interface for Ruby web frameworks. Since Heroku runs rack apps well, it makes sense to plan our deployment to it.
That decision also decides something else for us. Heroku uses PostgreSQL for it’s main database, so that’s what we’ll use too.
There are two things we need to do:
- Connect to our instance of PostgreSQL
- Make our app work with active record
Let’s deal with active record. We can install a gem to get support for it. Add this to your gem file:
gem "activerecord" gem "sinatra-activerecord"
Then, back on the command line (and in your app folder), run
bundle to install the gems.
main.rb file, require the dependency:
Now, we can add the connection string to PostgreSQL. If you need a guide to setting up PostgreSQL on your Mac read this.
The connection string will include a production (Heroku) call as well as a call to your local database:
ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'] || 'postgres://localhost/your_db_name')
You can see here that the production version will connect to your Heroku database when you’ve deployed the app. Otherwise, you’ll connect to your local PostgreSQL installation and a database name of your choosing.
Let’s say you are building a blog application. Now that you are connected to the database, you can use active record to get your posts:
get '/' do @posts = Post.order(created_at: :desc) erb :home end
If we want to display a list of posts on the home page, we can grab them from the database like this:
@posts = Post.order(created_at: :desc)
This assumes that your database table is called
posts and you have a field named
Active record will grab all your posts and make them available in the
@posts variable. That means in our
home.erb view we can do something like this:
<% @posts.each do |post| %> <h3><%= post.title %></h3> <%= post.body.truncate(150,:separator => ' ') %><br /> <a href="/view/<%=post.urlword%>">Read</a> <% end %>
We are just looping over the list of posts that will be rendered as HTML. This line of code:
<%= post.body.truncate(150,:separator => ' ') %> uses some Ruby magic to truncate the post body.
<a href="/view/<%=post.urlword%>">Read</a> creates a slugged url so that you have SEO friendly links.
How do we read the linked post? We need to add an action to our
get '/view/:link' do link = params[:link] @post = Post.find_by_urlword(link) erb :view end
You can see that we are asking for the URL parameter that I’ve named
link. This will contain the slugged name for our post.
Then, we use active record’s
find_by_fieldname method to retrieve the post from our database.
@post will have our record in it. We can access it like this (for example):
<%= @post.title %> to display the post title.
Now, you have a basic but complete Sinatra application that connects to PostgreSQL and queries it for blog posts.