Padrino Blog Tutorial using Postgres & DataMapper
Recently I’ve been wanting to experiment building websites with Ruby, but without using Rails. I’ve built a few small Sinatra applications, but I really miss having those basic MVC tools that Rails provides. It’s amazing how much easier things are when you have some nice routing and controller helpers. This led me to trying out Padrino, and I have to say it’s looking quite interesting.
Although the Padrino website does have a build-your-own-blog tutorial, it is using ActiveRecord and the HAML view template language. It’s not that I dislike either of these, but I did want try some other tools, such as DataMapper and straight up ERB for the views. As I couldn’t find any good tutorials out there I decided to use that Padrino tutorial as inspiration for my own post. Hopefully you will find it useful.
I will be borrowing heavily from the original Blog Tutorial, so if you’re happy enough using ActiveRecord and HAML, then please do go read that.
Okay, enough of the introductions, let’s get stuck in.
Installation
Presuming you already have Ruby installed on your system (I’ll be using Ruby 2.2.0 for this tutorial, although 1.9.3+ should be fine), our first task will be to install the latest version of the Padrino framework;
$ gem install padrino
At the time of writing this will install v0.12.4. For more details on installation please take a look at the official installation guide. Once this has finished installing, you’ll have all the necessary dependencies and we can begin building our Sample Blog.
New Project
Like with Rails, the easiest way to create a new project is via the Padrino generator. This will generate a skeleton application with all the appropriate files needed to build our application. Padrino is an agnostic framework and supports using a variety of different view template languages, testing frameworks, database components, and so on.
For our blog, we’ll be using the following components;
- PostgreSQL database
- DataMapper ORM
- ERB template language
- Twitter Bootstrap framework
- RSpec testing framework
- SASS stylesheet language for generating CSS
- jQuery JavaScript library.
You can learn more about generators in the Padrino generators guide.
Although we won’t be using RSpec, SASS or jQuery in this particular tutorial, it will be useful to have them in place ready for when you build in more functionality. Now we know what components we’re going to be using, let’s generate our new project;
$ padrino g project sample_blog -a postgres -d datamapper -e erb -t rspec -c sass -s jquery -b
Note the -b
flag at the end of the previous command. This instructs bundler to install all dependencies after it has finished generating the project. If you leave that off then you’ll need to make sure to run bundle install
manually. Next;
$ cd sample_blog
Now that we’re in the root or our application let’s take a closer look at a few of the more important files and directories, before we continue.
Gemfile
– include necessary GEM dependencies for your app here.app/app.rb
– the core application configuration.config/apps.rb
– defines which applications will be mounted.config/database.rb
– connection settings for your chosen database adapter.
And a few important directories;
app/controllers
– define your application routes here.app/helpers
– your application helper methods.app/views
– controllers will look here for view templates to render.lib
– put extensions, libraries or other code for your project here.public
– place application images, stylesheets and Javascript files here.spec
– your application tests.
So we can connect to our database we need to make sure we have all the correct settings configured properly - I’m going to presume you already have Postgres installed at this point but if you haven’t then I recommend you read the documentation. We’ll be using a separate configuration file for the database settings. Copy the following to config/database.yml
;
---
development: &defaults
adapter: postgres
database: sample_blog_development
username: USERNAME
password: PASSWORD
host: 127.0.0.1
test:
<<: *defaults
database: sample_blog_test
production:
<<: *defaults
database: sample_blog_production
USERNAME
and PASSWORD
should be replaced with the settings you used when installing Postgres. We’ll also need to edit the config/database.db
so that Padrino knows that it should be using our new YML configuration file. Uncomment the follow line;
DataMapper.setup(:default, YAML.load_file(Padrino.root('config/database.yml'))[RACK_ENV])
On my system I don’t need to specify a user when connecting to the database, so I had to remove the root
user from the DataMapper.setup()
commands;
when :development then DataMapper.setup(:default, "postgres://localhost/sample_blog_development")
when :production then DataMapper.setup(:default, "postgres://localhost/sample_blog_production")
when :test then DataMapper.setup(:default, "postgres://localhost/sample_blog_test")
Padrino Admin Panel
Padrino comes with a nice Admin Dashboard to help us manage and create/edit users and posts for our blog. Back in the console, enter the following;
$ padrino g admin
$ bundle install
This will create admin as a sub-application within your project, which will be mounted at boot by config/apps.rb
.
The admin panel installation tells us that we need to create the database, run migrations and seed the database, as follows;
$ padrino rake db:create
$ padrino rake db:migrate
$ padrino rake db:seed
When you run rake db:seed
you will be prompted to enter an email and password. Be sure to remember these otherwise you won’t be able to log in to the admin panel!
Read more about the dashboard in the Admin Panel Guide.
Since Padrino 0.10.0, all generated models are placed at the top level directory of the project in a models
directory. This seems a bit odd to me so if you wish, you can move the admin models
to live under the root admin
directory before continuing. It is however, not required.
Basic Routes
Before trying out our new app it might be useful to set up some simple routes. Let’s add some “homepage” and “about” page routes. Open up the app/app.rb
file and enter the following;
Be sure to check out the Padrino controllers guide for a comprehensive overview of the routing system.
Start Your Engines
Now that our Padrino application has been generated, the database configured, and our admin panel installed, we can boot up the Server. Before we do that though, we’re going to switch our application from using the default WEBrick server, and use Thin instead. Open up the Gemfile
and uncomment the line;
gem 'thin'
and then make sure you run;
$ bundle install
That done, we simply execute the following in the terminal;
$ padrino start
(Note: if you are getting any “unresolved specs” errors then you may need to prefix all padrino
commands with bundle exec
.)
If all is successful the terminal should output something like this;
=> Padrino/0.12.4 has taken the stage development at http://127.0.0.1:3000
Thin web server (v1.6.3 codename Protein Powder)
Maximum connections set to 1024
Listening on 127.0.0.1:3000, CTRL+C to stop
At this point you’re ready to view your new website!
Open your web browser and visit the URL; http://localhost:3000
. If all is well then you should see the homepage message; Hello World!
. You can jump into the admin panel by going to the URL; http://localhost:3000/admin
.
You’ll need to log in with the admin credentials you specified during the rake db:seed
command performed earlier. Feel free to explore this area and checkout the existing accounts. We’ll come back to this in more detail later.
Worth noting here is that Padrino has full support for code reloading in development mode. This means you can keep the Padrino server running and any time you change your source code, you can just refresh the browser and all changes will be automatically displayed. You might want to open up a new terminal and cd
to your directory and keep the server running.
To read more about terminal commands, take a look at the Development and Terminal Commands guide.
Creating Posts
So far so good, but this isn’t going to be much of a blog without any blog posts. Let’s implement the functionality to write and view posts!
We start off by creating a Post
model that has a title, body text, and a couple of timestamps. As mentioned earlier, Padrino creates new models in the top level directory so to give our application a better structure we’re going to tell it to generate these in a different location. By appending the command with an -a
option the models will be placed in the supplied sub-app directory (in this case app
);
$ padrino g model post title:string body:text created_at:datetime updated_at:datetime -a app
apply orms/datamapper
apply tests/rspec
create app/models/post.rb
create spec/app/models/post_spec.rb
create db/migrate/002_create_posts.rb
The Post
model will be created automatically when you run the migration;
$ padrino rake db:migrate
Next we need to create a controller so that we can display our posts;
$ padrino g controller posts get:index get:show
create app/controllers/posts.rb
create app/views/posts
This will create a posts controller with the standard :index
and :show
routes, so we can now open up the file and give it some instructions on what to do when someone hits these routes;
This defines routes that can be accessed via our application. The “http method” get
starts off the declaration followed by a symbol representing the “action”. Inside the block we store an instance variable fetching the necessary objects and then render an ERB view template. This should look quite familiar to anyone coming from Rails or Sinatra.
Now we need to create views for these :index
and :show
controller actions;
Padrino Admin makes it easy to create, edit and delete records, but before we can use this for our Posts, we need to tell Admin how to do this by running the following command;
$ padrino g admin_page post
create admin/views/posts
create admin/controllers/posts.rb
create admin/views/posts/_form.erb
create admin/views/posts/edit.erb
create admin/views/posts/index.erb
create admin/views/posts/new.erb
insert admin/app.rb
Note: make sure to use padrino g admin_page
after the creation of your model and their migration.
If your server is running (padrino start
) then go to the admin panel http://localhost:3000/admin
and login using your credentials as set previously. You should now see two tabs; one for Posts and the other for Accounts. Click on the Posts link.
Go ahead, write some posts!
Now we have a few posts in the system we can visit our :index
route. Visit the http://localhost:3000/posts
URL and voila! All your wonderful posts!
You can see all the routes we’ve defined so far by using the padrino rake routes
command:
$ padrino rake routes
URL REQUEST PATH
(:about) GET /about_us
(:posts, :index) GET /posts
(:posts, :show) GET /posts/show/:id
This can be helpful in understanding the mapping between controllers and URLs.
Assigning Posts to an Account
So far a post is not associated to any particular user, this might be okay for some, but if you wish to have others write for your blog then we need to let every post have an author. Let’s revisit our Post model. We’ll start by adding a new migration to attach an Account to a Post.
$ padrino g migration AddAccountToPost account_id:integer
apply orms/datamapper
create db/migrate/003_add_account_to_post.rb
This creates a new migration with the desired field attaching the account_id
to the post. Before running the migration we’ll want to modify this file and assign any existing posts to a user;
We also need to give the Post
model an association with the Account
, and while we’re there, let’s add a couple of Post
validations.
Remember, every time we change the database we need to run the migration;
$ padrino rake db:migrate
=> Executing Rake db:migrate ...
Our post model now has appropriate associations and validations. We also need to go inside the Admin Panel and make some changes so that the account (using current_account
) is saved when a new post is created.
As we now have a post author, we can update the post views to show their name;
and also;
If you create a bunch of posts as another user (create new users in the Admin Panel…and don’t forget to log in as them!), then you’ll be able to see which posts were written by which user.
Site Layout
Things are going well, but navigating our site is annoying and it certainly won’t be winning any beauty contests. Let’s fix that.
We’re going to create a site-wide template, called a “layout”, which acts as a container for the content templates yielded by each route. This will be used to create a consistent structure between each page of the application, giving us a navigation menu and a sidebar on every page.
I’m going to use Twitter Bootstrap to get us up and going quickly. Create a new file app/views/layouts/application.erb
and paste in this Bootstrap template;
Refresh and bask in the glory of your brand new theme!
As you can see, I’ve included some dummy sidebar elements to flesh out the design a little. Using the default Bootstrap CSS/Javascript files this template is a typical, if somewhat simple, theme as used on many blogs.
The official Padrino Blog Tutorial also covers how to deploy your application to Heroku, so if you need help then I recommend you go read that guide.
There should be enough here for you to forge on and expand the functionality to include many more blogging features.
I may even write some follow up tutorials, such as how to generate RSS feeds, implement a commenting system, and perhaps even how to protect your blog from comment spammers by using Wordpress’ Akismet. Keep your eyes peeled!