I have those models
User, Developer, App, Permission
- A User can have Default Permision
- A User can have Permission for Different Application
- A user can install Multiple Applications
- A User can also be a Developer of an Application
- A Developer is still a User and can have all use开发者_如何学Pythonr'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
- 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.
- 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
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.
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.
精彩评论