Reputation: 349
I have a Rails app where Users have Memberships to Projects (and other things, polymorphically). Users also have Roles. I want User#projects to work like a normal ActiveRecord find, but I also want administrators to have access to every project.
For a while I've been doing this:
class User < ActiveRecord::Base
has_many :memberships, :dependent => :destroy
def projects
if has_role?(:admin)
Project.find(:all)
else
Project.find(:all, :include => :memberships, :conditions => ["memberships.user_id = ?", id])
end
end
end
class Project < ActiveRecord::Base
has_many :memberships, :as => :member, :dependent => :destroy
end
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :member, :polymorphic => :true
end
But I'd really rather do something like this:
class User < ActiveRecord::Base
has_many :memberships, :dependent => :destroy
has_many :projects, :through => :memberships, :source => :member, :source_type => "Project"
end
so that I can use named_scope more regularly (e.g. 'alfred.projects.recent.active'). The
This works if you add new Memberships for admins automatically, but it quickly gets out of hand.
I want to keep the User#projects interface. What's the right track here?
Many thanks.
Upvotes: 2
Views: 243
Reputation: 6324
I'll insert a shameless plug for RESTful_ACL: http://github.com/mdarby/restful_acl/tree/master
Upvotes: 0
Reputation: 15596
I personally don't like to spread authorization concerns across models in the way you are trying to do it.
There are several reasons for this (the main being that in the end it usually leads to a non-RESTful design). The other one lies in the problem of ambivalent methods.
Think about it.
What does user.projects
mean in your system? In your model it has two meanings: it means
If you modeled your system this way, you would necessary end up with a bunch of methods with many different meanings, ie. purposes (think about a case in which you have three, four or more roles), which is not a good practice. There are more reasons, though. Eg. what if some user had more than one role? Admins are usually normal users, too.
What is the "right" solution then? Well, there are maybe more pf them, but the one I like and use right now is the one used by rails-authorization-plugin. Define roles in models and implement the authorization logic in controllers and views. Check out the plugin to see more.
Hope that helps! If not, just leave a comment.
Upvotes: 0
Reputation: 3068
Take a look at activefx's restfull authenticaion tutorial: (restful authentication tutorial) It is a rails app with the following features:
CURRENT FEATURES
- Login / Logout
- Restful, with the exception of the "activate" action
- Namespaced admin and user sections
- OpenID Authentication with support for incomplete OpenID profiles
- Roles and permissions
- Administrative user controller
- Set roles, activate, enable / disable users
- Login, permission, and access denied redirection system
- Member list and public profiles for logged in users
- Activation, with option to resend activation code
- Beta invitation system
- easy on/off functionality, add/remove invites, send emails to
- pending users
- Forgot Password / Reset Password
- Change Password
- Failed login attempts database logging
- Recaptcha displayed for more than 5 failed logins
- Helper methods (link_to_user, if_admin?, etc.)
This thread will explain how you give owner and administrator access. #28.
Good luck.
Upvotes: 1