Adding Authorization Using Devise Posted on February 28th, 2011
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.
git clone git@github.com:baileylo/blog.git git checkout -b blogCreated 0ba92371c2998caf362827987a82050708e9cd25
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: [gist id=846956] 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: [gist id=846957] diff 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 generate migrate addUserIdToPosts user_id:integer $ rake db:migrate
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. @post = Post.new(params[:post]) @post.user = current_user
diff 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 Now you have a full authorized blog. Come back next week to see user customizations.