Rails Authentication with Devise and CanCan – Customizing Devise Controllers

I’m tired of spending loads of time creating user authentication systems with permissions or swimming against the current to customize what’s available. There’s great open source stuff out there but until now, I haven’t gotten the full package with really easy customization.

The Devise and CanCan combo for user authentication and permissions in Rails is my combo of choice.

With Devise and CanCan, you can create a customized authentication and registration process in 15 minutes, and spend another 15 minutes implementing roles and permissions.

Rails Beauty
It’s pure beauty.

Note that the code here uses Rails 3. The difference in Rails 3 and Rails 2 code for this purpose should be minimal, but please refer to the documentation for differences.

Let’s start with authentication using devise.

Step 1 – Installation

gem install devise
rails generate devise:install
rails generate devise user

Step 2 – Configuration
Configuration is super easy with Devise. Just choose which of the 11 available modules you would like to include in your authentic model (most up-to-date list here):

  1. Database Authenticatable: encrypts and stores a password in the database to validate the authenticity of an user while signing in. The authentication can be done both through POST requests or HTTP Basic Authentication.
  2. Token Authenticatable: signs in an user based on an authentication token (also known as “single access token”). The token can be given both through query string or HTTP Basic Authentication.
  3. Oauthable: adds OAuth2 support
  4. Confirmable: sends emails with confirmation instructions and verifies whether an account is already confirmed during sign in.
  5. Recoverable: resets the user password and sends reset instructions.
  6. Registerable: handles signing up users through a registration process, also allowing them to edit and destroy their account.
  7. Rememberable: manages generating and clearing a token for remembering the user from a saved cookie.
  8. Trackable: tracks sign in count, timestamps and IP address.
  9. Timeoutable: expires sessions that have no activity in a specified period of time.
  10. Validatable: provides validations of email and password. It’s optional and can be customized, so you’re able to define your own validations.
  11. Lockable: locks an account after a specified number of failed sign-in attempts. Can unlock via email or after a specified time period.

easy_button
I chose 5 of the 11 modules and configured with the following code:

# In your model
 class User < ActiveRecord::Base
    devise :database_authenticatable, :confirmable, :recoverable, :rememberable, :trackable, :validatable
end
 
# In your migration
create_table :users do |t|
    t.database_authenticatable
    t.confirmable
    t.recoverable
    t.rememberable
    t.trackable
    t.timestamps
end
 
# In your routes
devise_for :users

Step 3 – Use It!

# In your controllers
before_filter :authenticate_user!, :except => [:some_action_without_auth]
# Access Current User
def index
    @things = current_user.things
end

This simple modular approach to authentication is hot. Devise also makes it really easy for you to customize views. The out-of-the-box views are great for prototyping, but if you need more, just generate the views and edit them:

rails generate devise:views

Devise will generate all of the views it is using and place them in an app/views/devise directory. Now you have complete control over your views.

The next thing you might want to do is customize your controllers. This is a bit more tricky with devise and we’ll get to that in a minute. Right now I want to touch on permissions and then I’ll tie it all together.

Let’s consider an example where your website is in Alpha/Beta or maybe an internal tool. You want to restrict user registration to only an administrator. Enter CanCan created by Ryan Bates.

CanCan

CanCan is a great gem for implementing model permissions. The main reasons I chose CanCan are:

  • The code written to check permissions is very readable
  • The code written to declare permissions is very concise and readable
  • It keeps permission logic in a single location so it is not duplicated across controllers, views, etc.
  • Aliasing actions (read = index and show) creates more concise and readable code

Ryan Bates has a great screen cast on using CanCan here, but I do not recommend using his roles mask method (mentioned in the screen cast). It certainly works but it’s bad database design and you will feel the pain later.

After you install CanCan (instructions here), I recommend you set up a typical users HABTM roles relationship. So you end up with migrations that look like this:

class CreateRoles < ActiveRecord::Migration
  def self.up
    create_table :roles do |t|
      t.string :name
      t.timestamps
    end
  end
 
  def self.down
    drop_table :roles
  end
end
 
class UsersHaveAndBelongToManyRoles < ActiveRecord::Migration
  def self.up
    create_table :roles_users, :id => false do |t|
      t.references :role, :user
    end
  end
 
  def self.down
    drop_table :roles_users
  end
end

And your models look like this:

# User Model
class User < ActiveRecord::Base
  has_and_belongs_to_many :roles
....
# Role model
class Role < ActiveRecord::Base
  has_and_belongs_to_many :users
end

The next step is to create your Ability class that will define permissions. Mine looks like this:

class Ability
  include CanCan::Ability
 
  def initialize(user)
    user ||= User.new # guest user
 
    if user.role? :super_admin
      can :manage, :all
    elsif user.role? :product_admin
      can :manage, [Product, Asset, Issue]
    elsif user.role? :product_team
      can :read, [Product, Asset]
      # manage products, assets he owns
      can :manage, Product do |product|
        product.try(:owner) == user
      end
      can :manage, Asset do |asset|
        asset.assetable.try(:owner) == user
      end
    end
  end
end

Most of this is application specific but you can see some conveniences right away. For example, the super admin role “can manage all”. That line is saying “If the user has the super_admin role, he may perform any action on any model.” Easy enough. Also notice that the product team can “read” products and assets. This means that they can access the index or show action of either of those models. You can pass a block to the can method for more complicated permission checks, but that is beyond the scope of this post and pretty easy to figure out.

Let’s take a look at the role method. I store role names as CamelCase strings in the database but I access them with underscores which is more ruby like. The method looks like this:

def role?(role)
    return !!self.roles.find_by_name(role.to_s.camelize)
end

Tying it all together

Now let’s go back to the situation I mentioned earlier – you want to protect user registrations. This requires us to use CanCan to check for permissions but customize the Devise Registrations controller to restrict access.

One way to do this is to copy the devise controllers into your controllers directory and start customizing. That may be the best way to go and it’s certainly an obvious path, but all I want to do restrict registration. Should I really have to re-implement the registrations controller to do that? For now, I will not. It might make sense when there are more customizations. Instead I inherit from the Devise Registrations controller. Here are the steps:

Step 1 – Create the controller
$ mkdir app/controllers/users
$ touch app/controllers/users/registrations_controller.rb

Step 2 – Add the custom functionality

class Users::RegistrationsController < Devise::RegistrationsController
  before_filter :check_permissions, :only => [:new, :create, :cancel]
  skip_before_filter :require_no_authentication
 
  def check_permissions
    authorize! :create, resource
  end
end

The check permissions method is really simple. It calls the CanCan method, authorize!, and checks if the current user can create users. We use resource here because devise uses resource to refer to the model that can be authenticated. Also notice how I removed the require_no_authentication filter, a Devise filter which allows access to actions without authentication.

Step 3 – Tell your routes to go to the new controller

# replace devise_for :users with:
devise_for :users,  :controllers => { :registrations => "users/registrations" }

Step 4 – Handle the CanCan::AccessDenied exception
At this point if you hit the users/sign_up page when not logged in, you will notice that a CanCan::AccessDenied is thrown. This exception is thrown anytime permission is denied so you should customize it to your liking. I put the handler in my ApplicationController:

class ApplicationController < ActionController::Base
  ...
  rescue_from CanCan::AccessDenied do |exception|
    flash[:error] = exception.message
    redirect_to root_url
  end
  ...
end

I realize I skipped some steps in here but this post + Devise documentation + CanCan documentation should help you set up authentication with roles and permissions very quickly. Let me know if you have any questions. Enjoy!

UPDATE

A part 2 of this post is now available

No TweetBacks yet. (Be the first to Tweet this post)
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

This entry was posted in Software and tagged , , , , , , , . Bookmark the permalink. Both comments and trackbacks are currently closed.

65 Comments

  1. David Wormuth
    Posted July 30, 2010 at 1:44 pm | Permalink

    There is a very nice devise_invitable module that also allows you to send invitations to users (cutting down on administrative overhead). I’ve had good luck with the version from rymai:

    http://github.com/rymai/devise_invitable.git

    rymai’s fork works on Rails 3/Devise 1.1.1 and is a fork from Sergio Cambra’s work that hasn’t caught up to Rails 3 yet :)

  2. Posted July 30, 2010 at 1:48 pm | Permalink

    @David – Very cool! I will give it a try this weekend. Here is the working link: http://github.com/rymai/devise_invitable

  3. Posted July 31, 2010 at 7:24 pm | Permalink

    This is really cool. I am now trying the same solution.. thanks for your nice hint of the whole process. :)

  4. Posted August 1, 2010 at 9:13 pm | Permalink

    nice ~ thanks !

  5. Kenny
    Posted August 23, 2010 at 10:58 am | Permalink

    Tony,
    Thank you for this post. It was really helpful. Could you please elaborate on why using Ryan Bates’ Roles approach is “bad database design and you will feel the pain later.” Is it because of the limitation in the number of roles? Were there any other disadvantages that you encountered?

  6. Posted August 30, 2010 at 3:24 pm | Permalink

    Thanks for the write up Tony, was a nice reminder/walk through on how to get things setup. I’m also a fan of Devise, and have used cancan before. I found this post from searching for discussions of what others are doing for roles as well.

    Kenny,

    I think he said that for a couple reasons: Ryan’s solution is fairly basic and a bit brittle (and he certainly didn’t say it was THE way to do it or anything, so not at all a criticism). IIRC he used the bitmasked solution, which will break if you have to reorder things a bit, is harder to use if you need/want to store the roles in the db or elsewhere, etc.

    Breaking it out as Tony has done lets you define other attributes e.g. Role Display Name or something to show users of your site. In short, quick/dirty way in the screen cast, while something like the method here is probably want you want for a more longer term solution.

  7. Posted August 31, 2010 at 9:03 pm | Permalink

    @Kenny – I don’t think I could have said it better than Jack

  8. Jean
    Posted September 2, 2010 at 11:40 am | Permalink

    Could you please elaborate how you go about making the view files of Devise with integration of “roles” selection. ie. do you use selection boxes to pick the roles? And how does your code for this look like, and how does Devise know how to use these roles?

    I’ve been at this Devise + CanCan business for all day and haven’t been successful so far, I’m about to give up but was hoping you could shed some light on this.

    I tried RyanB’s railscasts, but keep getting all kinds of errors even though I’m running a clean install (Rails 3 + Ruby 1.9.2) and am now in the process of adding your solution, but don’t know how to add fields to the registration form to select which roles to add to the user.

    Also, I keep getting an error message when I create the app/controllers/users/registrations_controller.rb file, saying it can’t find the view files, but when I copy app/views/devise/registrations/ to app/views/users/registrations/ I again get different errors.

    Pleaaaase help :’(

  9. Posted September 2, 2010 at 11:58 am | Permalink

    I knew this question was going to come up and I was going to put it in a Devise + CanCan part 2 I am writing up. There is so much awesomeness I couldn’t fit it in one post and I also wanted to learn the libraries a bit more.

    Since this is worthy of an entire new post, I’m going to keep my response short and tell you that VERY soon there will be much better instructions on how to really rock out with these two libs.

    So what you want is this in your routes:

    devise_for :users,  :controllers => { :registrations => "users/registrations" }

    and you want that controller to inherit from the devise controller:

    class Users::RegistrationsController < Devise::RegistrationsController

    Then you want your registration views in /app/views/users/registrations
    If you get errors at that point, I need more information to help you.

  10. Jean
    Posted September 3, 2010 at 4:42 am | Permalink

    Thanks Tony, great help. I’m going to give it another try today so I’ll let you know how it turns out. In the mean time, I’ve marked this blog to watch for that part II. Looks like it’s going to be a good read!

    Thanks again.

  11. Jean
    Posted September 3, 2010 at 7:39 am | Permalink

    Well, I’ve followed your tutorial through the letter and I’ve managed to get it working, yay! Unfortunately, I still don’t know how to add a custom form field in the registration form to select the roles for that user. I managed to get the selection boxes with the available roles, I just don’t know how to insert them in the database and tell devise to leave the field alone.

    But I guess that’ll be part of your next blogpost, so I’ll be patiently waiting :)

  12. Robert
    Posted September 3, 2010 at 9:58 am | Permalink

    First off, thanks for the write up. I found this post while trying to integrate the two gems and it’s been VERY helpful. I’m glad to hear you’re working on a part 2! I would love to see how you would handle setting up a default role for a new member with your current HABTM setup.

  13. Posted September 5, 2010 at 1:41 pm | Permalink

    @Jean – have you made the attribute accessible? For example, in your user model:

    attr_accessible :role_ids

    @Robert – Glad you enjoyed the post! I will try and address all new questions in the post but if you want a default role, I would consider a couple methods. One method is to add a hidden field in the registration form with the value of the default role. Another is to add a before_save callback or some other ActiveRecord callback to your user model and set the default role in the callback method. More info on ActiveRecord callbacks here.

  14. prospex
    Posted September 5, 2010 at 5:41 pm | Permalink

    Thanks for the great post Tony. I have everything setup, however I have two issues.

    I can’t access my applications helpers within the devise views. I think this is related to devise being a rails engine within its own module.

    And I also can’t access the devise helpers current_user and user_signed_in? from within the cancan ability class. How do I get this to work?

  15. Gabe
    Posted September 6, 2010 at 3:43 pm | Permalink

    Hey Tony,

    Thanks for writing this intro to cancan + devise. I really hope that you’ll explain how to work with these libs if you have indeed copied the devise controllers into your controllers folder. ;)
    I think most apps that require devise and cancan are complicated enough that the controllers need to be tinkered with inside the controllers directory.

  16. Posted September 6, 2010 at 8:44 pm | Permalink

    @prospex – Something is wrong if you can’t access your application helper from your devise view. I can do it just fine. It also makes sense you can’t access “current_user” from a model for the same reason you can’t access any controller methods from your model.

    @Gabe – I will be talking about greater levels of customization for controllers in the next post. One thing I’ll be talking about is how to handle a situation where you only want admins adding users (no open registration). If you have anything specific you want me to talk about, leave a comment and I’ll try to cover it if I wasn’t planning to already.

  17. Gabe
    Posted September 7, 2010 at 12:11 pm | Permalink

    Hey Tony, I’d love to know how to make sure the DB isn’t being accessed constantly to read permissions/roles. I don’t know if that’s already the case, but from Ryan Bates’ technique, I gather that some consideration is needed to speed things when a HABTM relationship is used for defining roles. Thanks a billion!

  18. Ross Timson
    Posted September 7, 2010 at 12:35 pm | Permalink

    Interesting post, really looking forward to part 2 and hope it is winging it’s way soon.

    I’m looking to start a new project which would not have open registration and would rely on admin users to add other users so part 2 will be exactly what I’m looking for. I’m thinking about using MongoDB rather than a ‘traditional’ RDBMS, and think I will try embedding the Roles table into the User document (table).

    Depending on the length of part 2 you could maybe mention testing the solution with the latest tools.

  19. Robert
    Posted September 7, 2010 at 3:57 pm | Permalink

    Wow that was easy. All it took was:

    before_save :setup_role
    def setup_role
    self.role_ids = [2]
    end

    Thanks!

  20. Posted September 7, 2010 at 5:42 pm | Permalink

    Just a quick note to say thanks for taking the time to write this blog post, it helped me out.

  21. Gabe
    Posted September 8, 2010 at 10:02 pm | Permalink

    Another suggestion! :) None of the docs or tutorials explain how to create an admin account with devise. All I’ve seen is “rails generate devise Admin”. I would like to know how to register something that doesn’t use ‘registrable’. Do I use the console? or perhaps do I use registerable, and then remove that module once i’ve created the admin account?

  22. Posted September 9, 2010 at 4:33 am | Permalink

    @Gabe – I haven’t explicitly checked but Rails’ ActiveRecord query cache should be caching results of requesting role information multiple times in one request. If you need further optimization you will need to store the roles in the session or some other cache (memcached).

    @Ross – Yes the second post is coming along and should be available end of this week/early next week. Closed registration functionality has been asked for a bunch so I will cover that. Testing would also be great to cover but we’ll see if there’s room. My gut tells me there will be a third post shortly after the second post ;)

    @Gabe – To create an initial admin account, you would probably want to use seed data or create the Admin user in the console. As far as creating more admins, you may want a SuperAdmin role that can create new admins. In one of my previous apps I seeded the database with a SuperAdmin so there was always a way to login and add users. I would not use registerable and then remove it. What will happen when you need to bootstrap your application on another server?

  23. Brett
    Posted September 13, 2010 at 2:26 pm | Permalink

    Great tutorial. What’s unique about what I’m try to do is have Users, Projects, and then Roles between UsersProjects. users can have different roles for various projects, or none at all. What do you think? Can CanCan accommodate?

  24. Eager2KnowMore
    Posted September 13, 2010 at 8:24 pm | Permalink

    I think I’m close. Where does this go?

    def role?(role)
    return !!self.roles.find_by_name(role.to_s.camelize)
    end

  25. Posted September 14, 2010 at 5:00 am | Permalink

    @Brett – I believe CanCan can accommodate. CanCan is there to tell you what each role can do, not which role each user has. Assuming you have a typical set of roles for each product, you would define which users have those roles in the database and what those roles “can” do in the ability class.

    @Eager2KnowMore – That would go in whatever model has roles. In my case it’s the user model.

  26. Vincent
    Posted September 15, 2010 at 9:05 am | Permalink

    Hey Tony,

    configuring a Devise controller is only possible on the latest version of Devise?
    I can’t figure out how to do with 1.0.8 version, keeps using the gem version whatever I do.

  27. Posted September 15, 2010 at 9:11 am | Permalink

    @Vincent – Yes, I believe configuring a devise controller is a recent improvement. In my older apps I end up using available helpers such as “sign_in” and “sign_in_and_redirect.” It’s not my favorite way to use the library but it works.

  28. fcooker
    Posted September 16, 2010 at 10:57 pm | Permalink

    If I put this code in User model :

    before_save :setup_role
    def setup_role
    self.role_ids = [2]
    end

    It works but when I sign in with a user which has not the role [2] it is updated.
    It seems to work better with :

    before_create :setup_role

  29. Robert
    Posted September 22, 2010 at 8:46 am | Permalink

    @fcooker- I noticed that too and ended up putting in a catch ( but forgot to comment here ), so my callback looks like this now:


    def setup_role
    if self.role_ids.empty?
    self.role_ids = [3]
    end
    end

  30. Gabe
    Posted September 28, 2010 at 4:41 pm | Permalink

    This tutorial just keeps on giving! Thanks for the time and effort. I have almost everything setup, but one last thing is eluding me. I want to be able to edit other Users. When I’m logged in as super_admin, I can’t seem to access other Users’s attributes and edit them. Any suggestions? How do I generate the /users/:id/edit/ route for this, for example?

    Thanks again,

    Gabe

  31. Posted September 28, 2010 at 5:17 pm | Permalink

    @Gabe – There’s a few gotchas. I’ve been slacking but I’m going to write that post up tonight since lots of people want it. It may be more of a collaborative post but we’ll get you started.

  32. Posted September 29, 2010 at 10:27 am | Permalink
  33. Rye
    Posted September 30, 2010 at 1:30 am | Permalink

    Any chance you could post a sample app on github?

  34. ryan
    Posted October 31, 2010 at 1:41 pm | Permalink

    having followed your custom RegistrationsController example, i receive an error Not authorized to create nilclass. when trying to acces the new registration action. if specify authorize! :create, User instead of resource, i am able to access it.

  35. Posted November 4, 2010 at 10:47 am | Permalink

    I’ve gone through this tut, great by the way, but I’m having an issue with going to the sign_up page — I’m getting a No Route error, and when I look at rake routes, all I have is:

    new_user_session GET /users/sign_in(.:format) {:action=>"new", :controller=>"devise/sessions"}
    user_session POST /users/sign_in(.:format) {:action=>"create", :controller=>"devise/sessions"}
    destroy_user_session GET /users/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
    user_password POST /users/password(.:format) {:action=>"create", :controller=>"devise/passwords"}
    new_user_password GET /users/password/new(.:format) {:action=>"new", :controller=>"devise/passwords"}
    edit_user_password GET /users/password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"}
    user_password PUT /users/password(.:format) {:action=>"update", :controller=>"devise/passwords"}
    root /(.:format) {:controller=>"welcome", :action=>"index"}

    Any clue why I don’t have sign_up ? I haven’t gone through the second part of the tutorial yet because I’m assuming that I should have the first part working first.

  36. Posted November 4, 2010 at 11:09 am | Permalink

    Ok, if I put the :registerable method into the devise statement in the users model, then I get that page, but according to the tutorial, you don’t have this in there, am I just being too literal? Thanks so much – just trying to wrap my head around this

  37. Posted November 4, 2010 at 11:13 am | Permalink

    @Jason – Your observation is correct. My website didn’t need public registration so I left that module out.

  38. Posted November 5, 2010 at 7:18 am | Permalink

    @Tony — thanks, I figured as much — I just seeded the user and got it up and running, so onto Part 2 — thanks so much for the posts

  39. mrharrison
    Posted December 13, 2010 at 4:52 pm | Permalink

    I setup my system identical to yours, but I’m getting this message when I update a user profile. Don’t quite understand I’m a Noob.

    SQLite3::SQLException: no such table: roles_users: SELECT "roles".* FROM "roles" INNER JOIN "roles_users" ON "roles".id = "roles_users".role_id WHERE ("roles_users".user_id = 1 ) AND ("roles"."name" = 'SuperAdmin') LIMIT 1

    Any suggestions would help. Thanks

  40. mrharrison
    Posted December 13, 2010 at 5:33 pm | Permalink

    Figured it out, wasn’t paying attention to the two migrations you had setup, only did the first one.

    Thanks,
    Matthew

  41. Posted December 29, 2010 at 11:20 am | Permalink

    I did a post on Devise as well and it’s gotten a ton of views. Yours is way more detailed…I’ll have to start sending folks here! Great post. Thanks.

  42. Kristian Mandrup
    Posted January 5, 2011 at 7:48 am | Permalink

    Hi, nice article!

    I just want you to know, that I spent months creating a project Cream which attempts to make it dead simple to setup a complete Authentication, Authorization with Roles solution, using Devise and CanCan for your ORM of choice. I can recognize much of what I did in this article ;) Check out Cream on github! Cheers!

    Kristian

  43. Dan
    Posted February 4, 2011 at 7:43 pm | Permalink

    Thanks for the great post. One thing though…I found the code for role? a little confusing

    return !!self.roles.find_by_name(role.to_s)

    So I use this instead

    self.roles.exists?(:name => role.to_s)

  44. Julia
    Posted February 9, 2011 at 10:42 am | Permalink

    This is a minor question. Why do you use !! in

    !!self.roles.find_by_name(role.to_s.camelize)

    Does it do anything? Just trying to understand the code.

  45. Maciej Kowalski
    Posted February 21, 2011 at 4:56 am | Permalink

    this method don’t work with postgres:

    def role?(role)
    return !!self.roles.find_by_name(role.to_s.camelize)
    end

  46. Posted February 21, 2011 at 6:32 am | Permalink

    @mrharrison – You are missing a table. Maybe you forgot to run the migrations

    @Dan – Looks better!

    @Julia – Double bang !! will make that statement return false (boolean) if the role is not found

    @ Maciej – I don’t use Postgres but since everything is going through AR then it might be an AR bug? I suggest looking at the generated query and figuring out why it doesn’t work

  47. Posted February 28, 2011 at 6:19 pm | Permalink

    Tony, great tutorial, but I have the same problem like Gave.
    I can’t create admin acc through console because I can’t generate encrypted password and salt, token,…
    Can you help me with this?

  48. MC
    Posted March 13, 2011 at 4:28 pm | Permalink

    In general, it would be helpful if you specify where things go.
    For example you talk about the role method, but don’t specify where we should add this method. I know, most are obvious, but having a small text on top of the code sample specifying which file you are editing would help.

    Just something that I think would make the tutorial more clear for new users.

    Thanks again for your effort

  49. Adam
    Posted March 19, 2011 at 5:47 am | Permalink

    Awesom stuff. Detailed and very helpful. One question though…

    Although I understand how !! ( not not ) works I cant see how it would ever return false in the above code when a role DOES NOT exist.

    If you try to find a record using find_by_some_attribute and it doesnt exist then an empty array is returned and if you use !! on an empty array you gert

    !![] ==> true

    but in this context you actually want false.

    or am i missing something here?

  50. Jakub
    Posted April 6, 2011 at 7:11 am | Permalink

    It is great tutorial. I suggest that you at least mention: add line like gem ‘devise’, ‘1.2.1′ to your Gemfile.

8 Trackbacks

  1. [...] Administrators By Tony | Published: September 29, 2010 About two months ago I wrote an article on getting started with Devise and CanCan. Since then, I’ve implemented the Devise + CanCan combo on three projects and wrote a couple [...]

  2. [...] frameworks, doesn’t have anywhere near the number of pre-written plugins to solve issues like adding roles and permissions to your site or put together an e-commerce [...]

  3. By Rails Authorization and Authentication | Matt Slay on November 27, 2010 at 8:06 pm

    [...] these great articles on another blog that describes using Rails and CanCan together: Article 1: Getting Started with Devise and CanCan The article includes very detailed steps and code samples for both Devise and CanCan.  Article [...]

  4. [...] there any database-managed roll based access control Gems on Rails 3.0?I found devise + CanCan: http://www.tonyamoyal.com/2010/0… .But its roll is hard-coded (ex. Ability class).I want to use roll based permission control gem [...]

  5. [...] from Devise’s official github page, Asciicast’s episode on CanCan by Ryan Bates, and Tony Amoyal’s tutorial. I took most of the codes from these resources and then slightly modified it to meet my own needs. [...]

  6. [...] Starting to fall for Rails A combination of Devise and Cancan might be useful, as shown herehttp://www.tonyamoyal.com/2010/0…11:35amView All 0 CommentsCannot add comment at this time. Add [...]

  7. [...] $ rails generate devise:views 10. Formate os templates das views em app/views/devise Fonte: http://www.tonyamoyal.com/2010/07/28/rails-authentication-with-devise-and-cancan-customizing-devise-... [...]

  8. [...] then went ahead and installed cancan, partly referring to this guide - the approach seemed very clean, however, I needed different sign up forms for the different user [...]