AlexNikolaev94
AlexNikolaev94

Reputation: 1209

Authorization and associations between user and posts

I'm learning Ruby on Rails now, and in the process of learning I'm writing a simple blog. I'm stuck with a certain problem - I need to have two sessions - Admin session, in which an Admin can create, update and delete posts and create/update comments, and a User session, in which User can only create, update and delete HIS OWN comments, so that each post should belong to Admin and display his name, and each comment should belong to a certain User and display his own name (as a method of signing in/up I want a simple form with name, email and password or through Facebook/VK API)

Upvotes: 0

Views: 311

Answers (1)

max
max

Reputation: 101821

The key here is understanding the difference between authorization and authentication.

Authentication is being able to verify the identity of the user. This is what Devise solves. This involves logging the user in and out and keeping track of who the current user is.

Authorization is who gets to do what in the application. "User can only create, update and delete HIS OWN comments" is clear cut example of a authorization rule.

Most beginners are for some unexplainable reason drawn to the idea of jamming authorization into the authentication layer. So they set out to try to authenticate a Admin class and Visitor class and the authentication layer ends up like swiss cheese. To fix the first mess they add Single Table Inheritance or MTI which just aggravates the problem.

Instead if you view authorization as a linked but separate concern there is much simpler and tried solution: roles.

The simplest possible solution is using a bitmask (an integer column) together with ActiveRecord::Enum to denote the users role:

class AddRoleToUsers < ActiveRecord::Migration
  def change
    add_column :users, :role, :integer, default: 0
    add_index :users, :role
  end
end

class User < ActiveRecord::Base
  enum role: [:user, :admin]
end

Which will let you do stuff like @user.admin?. This works as long as you have a very simple scenario where roles are application wide and a user can only have a single role. For more complex scenarios you would often setup a Role model (pun not intended) and create a one-to-many or many-to-many relationship between users and roles. See the Rolify gem for an example of how this works.

You may want to have a look at some existing solutions for authorization and authentication and figure out how to integrate them before even attempting to reinvent the wheel.

Upvotes: 1

Related Questions