1

I have those models

User, Developer, App, Permission
  1. A User can have Default Permision
  2. A User can have Permission for Different Application
  3. A user can install Multiple Applications
  4. A User can also be a Developer of an Application
  5. A Developer is still a User and can have all user's privillage (Install applcation, default permission, permissions for each application)

Until now I have:

user.rb

class User < ActiveRecord::Base
  has_many :apps
end

app.rb

class App < ActiveRecord::Base
  has_many :permissions, :through => :app_permissions
end

permission.rb

class Permission < ActiveRecord::Base
  belongs_to :app
end

app_permission.rb

class AppPermission < ActiveRecord::Base
end

Questions

  1. How to distinguish users? (Regular, Developer) Is it better to use CanCan or Rails STI or Simple Roles Class? Please justify why is better to use any of those three solutions or something else.
  2. Is it better to create a Default_Permission model to separate application permissions from default permission?

EDIT:

If I miss any information please ask. I would like to see some different solutions and how each solution works. Thanks

Immo
  • 601
  • 1
  • 6
  • 19

2 Answers2

1

I would recommend the following:

Developer is a User object. Distinguish developers from users with a is_developer boolean in your schema. This will make it easier going forward to keep Users / Developers integrated (without switch statements). You can add a named scope to find developers specfically:

class User < ActiveRecord::Base
  named_scope :regular_users, :conditions => { :is_developer => false }
  named_scope :developers, :conditios => { :is_developer => true }
  #you can then call User.regular_users or User.developers
end

Alternatively, you could have User / Developer work as polymorphic associations. E.g.

class Role < ActiveRecord::Base
  belongs_to :entity, :polymorphic => true #with entity_id / entity_type in your schema
end

The downside to this approach is it will make your code more complicated for little or zero semantic gain.


I don't truly understand what you mean by default permission, but it seems to be a logic issue as opposed to a database. Does everyone have the default permission? Then you can add it on *after_create*, or when writing your logic, assume it's true (or controlled by a boolean flag). The following code will create a permission for each user that is default true after they are created (for existing users, you can add the permissions by hand / rake task).

class User < ActiveRecord::Base
  after_create :add_default_permission

  def add_default_permission
    Permission.default_permissions.each do |permission|
      self.app_permissions.create(:permission_id => permission.id)
    end
  end
end

As for default_permissions, I would suggest having an *is_default* boolean on the permissions table. This way, you can have multiple default permissions going forward (or remove default permissions later). As a default permission is a permissions, there's no need to differentiate the object models. I.e.

class Permission < ActiveRecord::Base
  named_scope :default_permissions, :conditions => { :is_default => true }
end

Finally, make sure to fully spell out all of your ActiveRecord associations, i.e.

class User < ActiveRecord::Base
  has_many :apps
  has_many :permissions, :through => :app_permissions, :as => :permissible #edited
end

class App < ActiveRecord::Base
  belongs_to :app_permission
  has_many :permissions, :through => :app_permissions, :as => :permissible #edited
end

class Permission < ActiveRecord::Base
  belongs_to :app_permissions
  belongs_to :permissible, :through => :app_permissions, :polymorphic => true #edited
end

class AppPermission < ActiveRecord::Base
  belongs_to :permissible, :polymorphic => true #edited
  belongs_to :app
end

When a user installs an app: EDITED BELOW FOR POLYMORPHISM

Class User < ActiveRecord::Base
  def get_required_app(app)
    required_permissions = []
    app.permissions.each do |p|
      if self.permissions.find(:first, conditions => { :permission_id => p.id } ).nil?
        required_permissions.push p
      end
    end
    required_permissions
  end

  def install_app(app)
    req = required_permissions app
    return req if req.count > 0
    #add user app
  end
end

Hope this helps you work through your problem and let me know if you need any additional information.

hayesgm
  • 8,678
  • 1
  • 38
  • 40
  • With default permissions I mean that a user will have some permission that will be default when installing an application. After installing the application user can modify the permissions for the specific application. – Immo Jul 09 '11 at 23:51
  • So permissions are for application / user? E.g. Bob installs 'Playground' with permission 'Run on swings', and later Jane installs Playground with permission 'Build a new seesaw'? – hayesgm Jul 10 '11 at 04:44
  • No. An application can write to disk, read from disk, delete from disk etc. User can have some predefined conditions e.g. Read from disk = true, delete from disk = false so everytime he installs a new application will have to only accept only permissions that he didn't accept with his default permissions.. – Immo Jul 10 '11 at 21:31
  • You should use a polymorphic relationship to define user / app permissions (see above, bottom). When a user wants to install an app, you can check to see what permissions the app has less the permissions a user has, and require the user to grant those permissions in order to install the app. The code above should guide you to how to set this scenario up. – hayesgm Jul 11 '11 at 03:03
0

I can't tell from your question what your specific business requirements are, but most people use a role-based pattern for permissions management. See this question for a discussion and recommendation.

Community
  • 1
  • 1
Joel Brown
  • 14,123
  • 4
  • 52
  • 64
  • How many different kinds of permissions are there? How many different users are there? Do users come and go frequently by comparison with the different ways in which typical users permissions are set up? The presumption around role-based security is that there are a relatively limited number of relatively static permission patterns - e.g. jobs/positions - and that many users have the same patterns of permissions and come and go frequently. If every user is ultimately going to have a unique set of permissions then role-based security may not be helpful. – Joel Brown Jul 09 '11 at 19:19