Skip to content

Commit

Permalink
updated to work
Browse files Browse the repository at this point in the history
  • Loading branch information
kristianmandrup committed Nov 19, 2010
2 parents 8fef722 + 89d5b90 commit 6f55735
Show file tree
Hide file tree
Showing 51 changed files with 840 additions and 614 deletions.
38 changes: 25 additions & 13 deletions README.markdown
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
# Generic Role strategies
# Generic Roles

Generic role strategies that share the same API and are easy to insert in any existing User model.
Comes with a Rails 3 generator to instantly configure your Rails 3 app with a Role strategy of choice.
Generic Roles is a common (generic) Roles API and implementation that specific Roles implementations for various ORMs can implement.
This library also comes with a Rails 3 generator that can configure an existing user model with a Role strategy of choice.
A similar generator should always be created for specific ORM implementations

I have developed the following *roles* gems for popular ORMs that all support the same roles generic API.
I have developed the following *roles* gems for popular Object Mappers that all support the same Roles Generic API.

* Active Record - [roles_active_record](http://github.com/kristianmandrup/roles_active_record)
* DataMapper - [roles_data_mapper](http://github.com/kristianmandrup/roles_data_mapper)
* Mongoid - [roles_mongoid](http://github.com/kristianmandrup/roles_mongoid)
* MongoMapper - [roles_mongo_mapper](http://github.com/kristianmandrup/roles_mongo_mapper))
Relational Database (SQL)
* Active Record - [roles_active_record](http://github.com/kristianmandrup/roles_active_record)
* Data Mapper - [roles_data_mapper](http://github.com/kristianmandrup/roles_data_mapper)

Feel free to roll your own ORM extension for your favorite ORM!
Mongo DB
* Mongoid - [roles_mongoid](http://github.com/kristianmandrup/roles_mongoid)
* Mongo Mapper - [roles_mongo_mapper](http://github.com/kristianmandrup/roles_mongo_mapper)

Couch DB
* Simply Stored - [roles_simply_stored](http://github.com/kristianmandrup/roles_simply_stored)

## Status update (12 sept, 2010)

Roles generic has now been refactored in order to tidy up the code base and make it even more generic, flexible and easy to extend. It should now work! Please let me know if you have any issues ;)
Note: Feel free to roll your own ORM extension for your favorite Object Mapper!

## Install

<code>gem install roles_generic</code>

## Roles generator

A Rails 3 generator is included to update an existing model with a roles strategy and a set of valid roles

### Usage example

<code>rails g roles_generic:roles --strategy admin_flag --roles guest admin</code>

This generator is currently (Oct. 10) experimental. Feel free to provide patches or bug reports ;)

## Usage

The library comes with the following role models built-in:
Expand Down Expand Up @@ -61,7 +73,7 @@ Creates and uses a binary field 'admin_flag', which when true signals that this
end
</pre>

## Example: Using an ORM
## Example: Using an Object Mapper

Data Mapper with persistent attributes :name and :admin_flag

Expand Down
12 changes: 7 additions & 5 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ begin
gem.email = "kmandrup@gmail.com"
gem.homepage = "http://github.com/kristianmandrup/roles_for_mm"
gem.authors = ["Kristian Mandrup"]
gem.add_development_dependency "rspec", "~> 2.0.0.beta.22"
gem.add_development_dependency "generator-spec", "~> 0.6.5"
gem.add_development_dependency "rspec", ">= 2.0.0"
gem.add_development_dependency "generator-spec", ">= 0.7"

gem.add_dependency "require_all", "~> 1.2.0"
gem.add_dependency "activesupport", "~> 3.0.0"
gem.add_dependency 'sugar-high', "~> 0.2.10"
gem.add_dependency 'rails3_artifactor', '~> 0.2.5'
gem.add_dependency "activesupport", ">= 3.0"
gem.add_dependency 'sugar-high', "~> 0.3.0"
gem.add_dependency 'rails3_artifactor', '~> 0.3.1'
gem.add_dependency 'logging_assist', '>= 0.1.6'

# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
end
Jeweler::GemcutterTasks.new
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.2.7
0.3.2
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require 'rails3_artifactor'

module RolesModel
module RolesGeneric
module Generators
class RolesGenerator < Rails::Generators::NamedBase
include Rails3::Assist::Artifact::Model
Expand All @@ -12,29 +12,17 @@ class RolesGenerator < Rails::Generators::NamedBase


class_option :roles, :type => :array, :aliases => "-r", :default => [], :desc => "Valid roles"
# TODO: Should detect ORM from file content instead!
class_option :orm, :type => :string, :aliases => "-o", :default => nil, :desc => "ORM of model"


# hook_for :orm

def self.source_root
@source_root ||= File.expand_path("../../templates", __FILE__)
end

def apply_role_strategy
self.class.use_orm orm if orm
def apply_role_strategy
insert_into_model name do
insertion_text
end
end

protected

def orm
@orm ||= options[:orm].to_s.to_sym
end

def default_roles
[:admin, :guest]
end
Expand All @@ -51,14 +39,19 @@ def role_strategy_statement
"strategy :#{strategy}\n"
end

def role_class_statement
[:one_role, :many_roles].include?(strategy.to_sym) ? 'role_class :role' : ''
end

def roles_statement
roles ? "valid_roles #{roles.join(',')}" : ''
roles ? "valid_roles_are #{roles.join(',')}" : ''
end

def insertion_text
%Q{
include Roles::#{orm.to_s.camelize}
#{role_strategy_statement}
#{role_class_statement}
#{roles_statement}
}
end
Expand Down
1 change: 1 addition & 0 deletions lib/roles_generic.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'require_all'
require 'active_support/inflector'
require 'sugar-high/not'
require 'sugar-high/array'
require 'set'
require 'roles_generic/namespaces'
require 'roles_generic/base'
Expand Down
42 changes: 40 additions & 2 deletions lib/roles_generic/base.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
module Roles
module Base
attr_accessor :orm_name
attr_reader :role_strategy

def valid_roles_are(*role_list)
strategy_class.valid_roles = role_list.to_symbols
end

def valid_role? role
strategy_class.valid_roles.include? role.to_sym
end

def valid_roles? *role_names
role_names.each do |role|
return false if !strategy_class.valid_roles.include? role.to_sym
end
true
end

def valid_roles
strategy_class.valid_roles
end
Expand All @@ -14,15 +26,41 @@ def roles(*roles)
strategy_class.valid_roles = Array[*roles].flatten.map { |r| r.to_sym }
end

def role_strategy strategy_name, options=nil
def set_role_strategy strategy_name, options=nil
include_strategy orm_name, strategy_name, options
end

class RoleStrategyId
attr_accessor :name

def initialize strategy_name
@name = strategy_name.to_s.underscore.to_sym
end

def type
@type ||= case name
when :one_role, :many_roles
:complex
else
return :simple if name
end
end

def multiplicity
@multiplicity ||= case name
when :many_roles, :role_strings, :roles_mask, :roles_string
:multi
when :one_role, :admin_flag, :role_string
:single
end
end
end

def include_strategy orm, strategy_name, options=nil
begin
module_name = "RoleStrategy::#{orm_name.to_s.camelize}::#{strategy_name.to_s.camelize}"
constant = module_name.constantize

@role_strategy = RoleStrategyId.new strategy_name
strategy_class_method = %Q{
def strategy_class
#{constant}
Expand Down
2 changes: 1 addition & 1 deletion lib/roles_generic/generic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def strategy name, options=nil
if options == :default && MAP[name]
instance_eval MAP[name]
end
role_strategy name, options
set_role_strategy name, options
end
end
end
Expand Down
18 changes: 2 additions & 16 deletions lib/roles_generic/generic/role.rb
Original file line number Diff line number Diff line change
@@ -1,24 +1,10 @@
module Roles::Generic::Role
module InstanceMethods
module InstanceMethods
def role_class
self.class.role_class_name
end

def get_roles _roles
raise "Role class #{role_class} does not have a #find_role(role) method" if !role_class.respond_to? :find_role
_roles = _roles.flatten.compact
_roles = _roles.select{|role| role.kind_of?(role_class) || role.kind_of_label?}
_roles.map! do |role|
case role
when role_class
role.name
else
role.to_s
end
end
end
end

module ClassMethods
def role_class_name
@role_class_name
Expand Down
30 changes: 30 additions & 0 deletions lib/roles_generic/generic/role_util.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module Roles::Generic::RoleUtil
# extract role symbols from roles
# should handle symbols, strings, arrays and Role instances
def extract_roles *roles
roles.flatten.map{|role| extract_role role}.compact
end

def extract_role role
role = case role
when Array
role.flat_uniq.first
else
role
end

if defined?(Role) && role.kind_of?(Role)
raise 'Role instances should have a #name method that reflects the role name' if !role.respond_to? :name
return role.name.to_s.to_sym
end

case role
when String, Symbol
role.to_sym
else
nil
end
end

extend self
end
Loading

0 comments on commit 6f55735

Please sign in to comment.