This week will focus on formatting the rails app to be more user friendly. If this is your first time to this site, please see the first post on making your owns rails blog. Before we start with this weeks topics I made some basic CSS and formatting changes that can be seen here. Currently the blog displays dates in RFC format and only shows the authors email. This week you’ll use Rails I8ln tools to build custom date formatting. We’ll also extend Devise, allowing users to login with a user name.
Custom Date Formatting
There are two main theories to Date Formatting. Building a time_format initializer or adding date formats to your locales file. Since date formats differ between regions it makes sense to place these formats in your locales file.
Open up config/locales/en.yml, app/view/posts/show.html.erb, and app/view/posts/index.html.erb and make these changes. In locales file, the format named “default” will be used if no format is specified. In the view file, those are L’s that have been added prior to the dates. L is a default rails helper method for localize and will apply the localization for that data in our case a timestamp. You can add as many differing formats as you’d like. You can call these by using the following code
<%= l Time.now, :format => :awesome %>
A cheat sheet of all ruby date formats can be found here. If you would like more information on locale files, Ruby on Rails has a good guide on it.
Adding usernames is a breeze with Devise. The first step to is create a migration to add the column. $rails g migration addUsernameToUser username:string
Open up the generated migration and make these changes then run the migration.
Since we plan to allow users to login using their username we’ve made it a unique key, the database will not allow more than 1 User to have the same username. Now that the column is created, modify the User model to allow editing and validation of username. We will also make sure that Devise is validating data in the forms. You can see the changes here, user.rb
Now that our model and database are set to handle usernames, we have to make sure our views can handle them. To do this we need to extend the default Devise views. Run the following commands and then edit the files as seen here. $ rails generate devise:views
For more information about this as well as how to let user recover their passwords using username or email please see the Devise wiki.
Now that we can edit, login and register with usernames, lets display them on our page. Edit post show and post index templates as seen here.
Check in next week were we will add comments to the posts.
This will cover how to use Devise as your user authentication system. In previous posts I’ve used AuthLogic which is a good solution, I just find Devise simpler to use and implement. This will extend from my article Rails 3 Blog Tutorial. I’d highly suggest going through that tutorial, or you can run these commands.
First add devise to your gemfile, gem â€œDeviseâ€. Then run the follow commands:
$ bundle install
$ rails generate devise:install
This will install the Devise gem and set up the Devise modules. You will be prompted for 3 steps:
Do step 1, step 2 and 3 should already be done. Once you have completed these steps run:
$ rails generate devise user
Open up your user model(app/models/users.rb). You will see a comment at the top listing possible devise modules. You can add and remove these as you wish. For this tutorial we’ll only use: database_authenticatable, registerable, recoverable, rememberable, trackable. Save the changes, and run:
$ rake db:migrate
Now if you run â€œrake routesâ€ you will see a series of /users/ routes setup automatically by Devise. Open up your application template, app/views/layout/application.html.erb and add the following code:
Restart your rails server, and then reload your page. You should see in the top right Login and Register links. Feel free to create an account and play around with Devise’s built in authentication and user validation.
Now we need to associate a specific author with a specific post. To do this will use another migration:
Rails migration generator will automatically read the migration name and realize that we’re adding the UserId column To the Posts table. Now we need to make the relationships between the models in ruby. Open up the user model(app/models/user.rb) and add â€œhas_many :postsâ€ within the class definition. Now open the posts model (app/models/post.rb) and add â€œbelongs_to :userâ€ within the class definition. diff
So far now we’ve created user authentication system and added user to a post. Open your posts controller (app/controllers/posts_controller.rb) and add the following line at the top of your class, but inside the class definition
before_filter :authenticate_user!, :only => [:edit, :update, :destroy, :create, :new]
This will apply Devise’s built in function authenticate_user! When the actions edit, update, create, new, and destroy are called. It will effectively require the user to be logged in to access these actions.
Prior to a post being saved, we’re going to want to set the â€œposterâ€ to be the user who is currently signed in. Devise provides the current_user helper which allows you access to the logged in user’s User object. Change the â€œcreateâ€ action in the posts controller to look like this.
This will assign the currently logged in user as the user for the post. Lets clean up the views a little big. Change your posts index.html.erb and show.html.erb files to look like this, app/views/posts/. diff
You may be getting error that reads: â€œundefined method `email’ for nil:NilClassâ€œ. These blogs were posted prior to having added the user migration. You can add an if statement to skip the user data when a Post doesn’t have a related User Object. But lets make a migration, run the following command $ rails g migration insertUserInAllPosts
Open up the generated migration, and make the following changes
. We named the migration â€œinsertUserInAllPostsâ€, the name is up to you. It is nice to have descriptive names for migrations; in the future you will waste less time figuring out what the migration does if it has a good name. diff
You may have noticed that we have removed the links to edit posts for other users, but they can still edit posts if they go directly to the url. To fix this we’ll use another â€œbefore_filterâ€. Open up the posts controller, app/controllers/post_controller.rb, and make the following changes: diff
This tutorial will cover the creation of a personal blog using Ruby on Rails 3. This tutorial assumes that you have Sqlite3, and Rails gem installed. There will be other applications used but their installation is explained as is needed.
First lets create our rails application and come up with some basic starting blocks for our blog. $ rails new blog
$ cd blog
$ rails generate scaffold post title:string body:text
$ rake db:migrate
$ rails -s
The first two commands create the base rails framework. The next command is where you see a lot of the benefit of using ruby on rails. It automatically created the migration files, model files, controller files, and view files for our new database object called â€œPostâ€.
Migrations are how rails tracks schema changes in your database. You can migrate the database up to a latest migration or roll down to a previous migration. Rake db:migrate is the command to make the schema changes for the latest migration. Rails -s creates a simple webbrick server; this server is good for development, but not production.
You should now be able to goto localhost:3000 where you will be greeted by a friend rails page. Of course you probably don’t want your users to see this page so remove public/index.html.erb and add a new route, ‘root :to => â€œposts#showâ€ to your configs.rb, seen here.
Once you reload your homepage you should see the friendly rails scaffolding. Feel free to create your first post!