This is a hack of EppO/rolify for specific purpose and for bypassing some limitations. We want only have users scoped on specific instance of resource. We are no really interesting by hierarchy. We want use Rolify for binding some resource through roles, the resources have absolutely need to be existing.
Add this line to your application's Gemfile:
gem 'scoped_rolify'
And then execute:
$ bundle
Or install it yourself as:
$ gem install scoped_rolify
We have added add_scope_role(role_name, resource)
method for mapped original add_role
method.
This method force argument resource to be existing, and add extra feature for root resource
discussed below.
usage:
You can't add right without instance of resource
user = User.find(1)
user.add_scope_role :admin # Thrown MissingResourceError
user.add_scope_role :moderator, Forum # Thrown InstanceResourceError
Only the following ways are possible
user.add_scope_role :moderator, Forum.first
user.add_scope_role :moderator, Forum.new
This method is mapped by #remove_scope_role
Those methods are mapped by #with_scoped_role
and method #with_any_scoped_role
An important enhancement here, the new methods return an ActiveRecord::Relation
instead array of result! Is a big feature for us.
usage:
The methods return users for asked roles
You can't call method without instance of resource
User.with_scoped_role :admin # Thrown MissingResourceError
User.with_scoped_role :moderator, Forum # Thrown InstanceResourceError
Only the following ways are possible
User.with_scoped_role :moderator, Forum.first
You can't play with none persisted object
In some case you can add right on child resource instead of parent resource, the problem is you haven't access directly to objects through Parent resource, for exemple
You grant user on specific Forum
, user.add_scope_role(:moderator, Forum.first)
the Forum
have one Category
, if you want get all moderators of this Category
you can't. This modification make this way possible.
moderator_john = User.new
moderator_jane = User.new
hack_category = Category.new
fair_hack_forum = Forum.new
blackhat_hack_forum = Forum.new
class Forum < ActiveRecord::Base
belongs_to :category
def root_resource
:category
end
end
class Category < ActiveRecord::Base
has_many :forums
end
hack_category.forums << fair_hack_forum
hack_category.forums << blackhat_hack_forum
moderator_john.add_scope_role(:moderator, blackhat_hack_forum)
moderator_jane.add_scope_role(:moderator, fair_hack_forum)
For get all moderators of this Category
User.with_scoped_role :moderator, hack_category, scope: :root
We have fixed a bug on has_role?
method for object none persisted
Possible enhancements
Refactoring on root resource API
Change
class Forum < ActiveRecord::Base
belongs_to :category
def root_resource
:category
end
end
to
class Forum < ActiveRecord::Base
belongs_to :category
scoped_roles belongs_to: :category
end
This way seem pretty nice, but need spend more time on it.
- Fork it ( http://github.com//scoped_rolify/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request