roles_active_record 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +13 -0
  5. data/LICENSE +20 -0
  6. data/README.markdown +178 -0
  7. data/Rakefile +28 -0
  8. data/VERSION +1 -0
  9. data/development.sqlite3 +0 -0
  10. data/lib/generators/active_record/roles/roles_generator.rb +46 -0
  11. data/lib/generators/active_record/roles_migration/roles_migration_generator.rb +54 -0
  12. data/lib/generators/active_record/roles_migration/templates/add_admin_flag_strategy.erb +14 -0
  13. data/lib/generators/active_record/roles_migration/templates/add_many_roles_strategy.erb +40 -0
  14. data/lib/generators/active_record/roles_migration/templates/add_one_role_strategy.erb +40 -0
  15. data/lib/generators/active_record/roles_migration/templates/add_role_string_strategy.erb +13 -0
  16. data/lib/generators/active_record/roles_migration/templates/add_roles_mask_to_users_migration.erb +13 -0
  17. data/lib/generators/active_record/setup/setup_generator.rb +40 -0
  18. data/lib/roles_active_record/base.rb +19 -0
  19. data/lib/roles_active_record/namespaces.rb +12 -0
  20. data/lib/roles_active_record/role.rb +24 -0
  21. data/lib/roles_active_record/strategy/multi/many_roles.rb +70 -0
  22. data/lib/roles_active_record/strategy/multi/roles_mask.rb +84 -0
  23. data/lib/roles_active_record/strategy/single/admin_flag.rb +53 -0
  24. data/lib/roles_active_record/strategy/single/one_role.rb +49 -0
  25. data/lib/roles_active_record/strategy/single/role_string.rb +51 -0
  26. data/lib/roles_active_record/strategy.rb +15 -0
  27. data/lib/roles_for_active_record.rb +13 -0
  28. data/lib/views/_multi_role_selector.erb.html +5 -0
  29. data/lib/views/_single_role_selector.erb.html +1 -0
  30. data/roles_active_record.gemspec +161 -0
  31. data/roles_for_ar.gemspec +165 -0
  32. data/sandbox/Rakefile +16 -0
  33. data/sandbox/add_role_to_users_migration.erb +13 -0
  34. data/sandbox/create_roles_migration.erb +12 -0
  35. data/sandbox/create_user_roles_migration.erb +13 -0
  36. data/sandbox/database.log +47 -0
  37. data/sandbox/database.yml +4 -0
  38. data/sandbox/development.sqlite3 +0 -0
  39. data/sandbox/migrate/201002508_create_roles.rb +11 -0
  40. data/sandbox/migrate/20102507_create_users.rb +11 -0
  41. data/sandbox/model_base.rb +46 -0
  42. data/sandbox/test.rb +13 -0
  43. data/spec/db/database.yml +4 -0
  44. data/spec/fixtures/many_roles_setup.rb +8 -0
  45. data/spec/fixtures/one_role_setup.rb +8 -0
  46. data/spec/migrations/admin_flag/004_add_admin_flag_to_users.rb +15 -0
  47. data/spec/migrations/many_roles/002_create_roles.rb +13 -0
  48. data/spec/migrations/many_roles/003_create_user_roles.rb +13 -0
  49. data/spec/migrations/one_role/002_create_roles.rb +12 -0
  50. data/spec/migrations/one_role/003_add_role_to_users.rb +13 -0
  51. data/spec/migrations/role_string/002_add_role_string_to_users.rb +13 -0
  52. data/spec/migrations/roles_mask/005_add_roles_mask_to_users.rb +13 -0
  53. data/spec/migrations/users/001_create_users.rb +11 -0
  54. data/spec/roles_active_record/admin_flag_spec.rb +71 -0
  55. data/spec/roles_active_record/generators/migration_spec_helper.rb +17 -0
  56. data/spec/roles_active_record/generators/roles_migration/admin_flag_spec.rb +67 -0
  57. data/spec/roles_active_record/generators/roles_migration/many_roles_spec.rb +57 -0
  58. data/spec/roles_active_record/generators/roles_migration/one_role_spec.rb +56 -0
  59. data/spec/roles_active_record/generators/roles_migration/role_string_spec.rb +40 -0
  60. data/spec/roles_active_record/generators/roles_migration/roles_mask_spec.rb +36 -0
  61. data/spec/roles_active_record/generators/setup_generator_spec.rb +40 -0
  62. data/spec/roles_active_record/many_roles_spec.rb +69 -0
  63. data/spec/roles_active_record/one_role_spec.rb +68 -0
  64. data/spec/roles_active_record/role_string_spec.rb +68 -0
  65. data/spec/roles_active_record/roles_mask_spec.rb +68 -0
  66. data/spec/spec_helper.rb +57 -0
  67. metadata +318 -0
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --format nested --color
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source :rubygems
2
+
3
+ gem "active_record", ">= 3.0.0.rc"
4
+ gem "active_support", ">= 3.0.0.rc"
5
+ gem "meta_where", ">= 0.6.0"
6
+
7
+ group :test do
8
+ gem "rspec", ">= 2.0.0.beta.19"
9
+ gem "yaml"
10
+ gem "logger"
11
+ gem 'database_cleaner'
12
+ gem "generator_spec", '>= 0.4.5'
13
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Kristian Mandrup
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,178 @@
1
+ # Roles for Active Record
2
+
3
+ An Active Record implementation of [roles generic](http://github.com/kristianmandrup/roles_generic)
4
+
5
+ ## Install
6
+
7
+ <code>gem install roles_active_record</code>
8
+
9
+ ## Update!
10
+
11
+ Now implements the [roles generic](http://github.com/kristianmandrup/roles_generic) Roles API
12
+ It also implements the following Role strategies:
13
+
14
+ * admin_flag
15
+ * many_roles
16
+ * one_role
17
+ * roles_mask
18
+ * role_string
19
+
20
+ ## Rails generator
21
+
22
+ Needs some more refactoring (see notes below!)
23
+
24
+ <code>$ rails g active_record:roles User --strategy admin_flag --roles admin guest</code>
25
+
26
+ ## Usage
27
+
28
+ Example: admin_flag Role strategy - generate migrations and model files
29
+
30
+ <code>$ rails g active_record:roles User admin_flag</code>
31
+
32
+ Example: admin_flag Role strategy - generate migrations only
33
+
34
+ <code>$ rails g active_record:roles_migration User admin_flag</code>
35
+
36
+ ## Role strategies
37
+
38
+ The library comes with the following role strategies built-in:
39
+
40
+ Single role:
41
+
42
+ * admin_flag
43
+ * role_string
44
+ * one_role
45
+
46
+ Multi role:
47
+
48
+ * many_roles
49
+ * roles_mask
50
+
51
+
52
+ ### Admin flag
53
+
54
+ Boolean *admin_flag* on User to indicate if user role is admin or normal user
55
+
56
+ ### Role string
57
+
58
+ String *role_string* on User that names the role
59
+
60
+ ### One role
61
+
62
+ *role_id* relation to *id* of *Roles* table that contain all valid roles
63
+
64
+ ### Many roles
65
+
66
+ *role_id* relation to *UserRoles* table that is the join table that joins a user to multiple roles in the *Roles* tables.
67
+
68
+ ### Roles mask
69
+
70
+ *roles_mask* integer that as a bitmask indicating which roles out of a set of valid roles that the user has.
71
+
72
+ Note: The following examples use RSpec to demonstrate usage scenarios.
73
+
74
+ ## Example : admin_flag
75
+
76
+ <pre>use_roles_strategy :admin_flag
77
+
78
+ class User < ActiveRecord::Base
79
+ include Roles::ActiveRecord
80
+
81
+ strategy :admin_flag, :default
82
+ valid_roles_are :admin, :guest
83
+ end
84
+ </pre>
85
+
86
+ ## Example : role_string
87
+
88
+ <pre>use_roles_strategy :role_string
89
+
90
+ class User < ActiveRecord::Base
91
+ include Roles::ActiveRecord
92
+
93
+ strategy :role_string, :default
94
+ valid_roles_are :admin, :guest
95
+ end
96
+ </pre>
97
+
98
+ ## Example : one_role
99
+
100
+ <pre>use_roles_strategy :one_role
101
+ class User < ActiveRecord::Base
102
+ include Roles::ActiveRecord
103
+
104
+ strategy :one_role, :default
105
+ role_class :role
106
+
107
+ valid_roles_are :admin, :guest
108
+ end
109
+ </pre>
110
+
111
+ ## Example : many_roles
112
+
113
+ <pre>use_roles_strategy :many_roles
114
+ class User < ActiveRecord::Base
115
+ include Roles::ActiveRecord
116
+
117
+ strategy :many_roles, :default
118
+ role_class :role
119
+
120
+ valid_roles_are :admin, :guest
121
+ end
122
+ </pre>
123
+
124
+ ## Example : roles_mask
125
+
126
+ <pre>use_roles_strategy :roles_mask
127
+
128
+ class User < ActiveRecord::Base
129
+ include Roles::ActiveRecord
130
+
131
+ strategy :roles_mask, :default
132
+ valid_roles_are :admin, :guest
133
+ end
134
+
135
+ </pre>
136
+
137
+ ## Rails generators
138
+
139
+ The library comes with a Rails 3 generator that lets you populate a user model with a given role strategy
140
+ The following role strategies are included by default. Add your own by adding extra files inside the strategy folder, one file for each role strategy is recommended.
141
+
142
+ * admin_flag
143
+ * role_string
144
+ * roles_mask
145
+ * one_role
146
+ * many_roles
147
+
148
+ _Important:_
149
+
150
+ The generators are a bit rusty and needs to be updated to take advantage of the [rails3_artifactor](http://github.com/kristianmandrup/rails3_artifactor)
151
+ Please see the [roles mongoid](http://github.com/kristianmandrup/roles_mongoid) for an example. You are most welcome to submit a patch to make it work for AR ;)
152
+
153
+ ### Generators
154
+
155
+ * active_record:roles
156
+ * active_record:roles_migration
157
+
158
+ Example: admin_flag Role strategy - generate migrations and model files
159
+
160
+ <code>$ rails g active_record:roles User admin_flag</code>
161
+
162
+ Example: admin_flag Role strategy - generate migrations only
163
+
164
+ <code>$ rails g active_record:roles_migration User admin_flag</code>
165
+
166
+ ## Note on Patches/Pull Requests
167
+
168
+ * Fork the project.
169
+ * Make your feature addition or bug fix.
170
+ * Add tests for it. This is important so I don't break it in a
171
+ future version unintentionally.
172
+ * Commit, do not mess with rakefile, version, or history.
173
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
174
+ * Send me a pull request. Bonus points for topic branches.
175
+
176
+ ## Copyright
177
+
178
+ Copyright (c) 2010 Kristian Mandrup. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gem|
4
+ gem.name = "roles_active_record"
5
+ gem.summary = %Q{Implementation of Roles generic API for Active Record}
6
+ gem.description = %Q{Makes it easy to set a role strategy on your User model in Active Record}
7
+ gem.email = "kmandrup@gmail.com"
8
+ gem.homepage = "http://github.com/kristianmandrup/roles_for_dm"
9
+ gem.authors = ["Kristian Mandrup"]
10
+ gem.add_development_dependency "rspec", "~> 2.0.0.beta.19"
11
+ gem.add_development_dependency 'database_cleaner', '~> 0.5.2'
12
+ gem.add_development_dependency "generator-spec", '~> 0.4.5'
13
+
14
+ gem.add_dependency "activerecord", "~> 3.0.0"
15
+ gem.add_dependency "activesupport", "~> 3.0.0"
16
+ gem.add_dependency "arel", "~> 1.0.0"
17
+ gem.add_dependency "meta_where", ">= 0.5.2"
18
+ gem.add_dependency "sugar-high", "~> 0.2.2"
19
+ gem.add_dependency "require_all", '~> 1.1.0'
20
+ gem.add_dependency "sugar-high", '~> 0.2.3'
21
+ gem.add_dependency "roles_generic", '~> 0.2.2'
22
+
23
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
24
+ end
25
+ Jeweler::GemcutterTasks.new
26
+ rescue LoadError
27
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
28
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
File without changes
@@ -0,0 +1,46 @@
1
+ module ActiveRecord
2
+ module Generators
3
+ class RolesGenerator < Rails::Generators::NamedBase
4
+ desc "Generate roles model for User"
5
+
6
+ argument :role_strategy, :type => :string, :aliases => "-r", :default => 'inline_role', :desc => "Create roles model for user"
7
+
8
+ hook_for :orm
9
+
10
+ def self.source_root
11
+ @source_root ||= File.expand_path("../../templates", __FILE__)
12
+ end
13
+
14
+ def apply_role_strategy
15
+ insert_into_model('user', role_strategy_statement)
16
+ end
17
+
18
+ protected
19
+
20
+ def match_expr
21
+ /< (.+?)\w+\s/
22
+ end
23
+
24
+ def role_strategy_statement
25
+ "role_strategy #{role_strategy}"
26
+ end
27
+
28
+ def role_strategy
29
+ options[:role_strategy]
30
+ end
31
+
32
+ def model_file(name)
33
+ File.join(Rails.root, "app/models/#{name}.rb")
34
+ end
35
+
36
+ def insert_into_model(model_name, insert_text)
37
+ model_name = model_name.to_s
38
+ file = File.new(model_file(model_name))
39
+ return if (file.read =~ /#{insert_text}/)
40
+ gsub_file model_file(model_name), match_expr do |match|
41
+ match << insert_text
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,54 @@
1
+ # require 'generators/migration_helper'
2
+ # require 'generators/role_migrations'
3
+ # require 'auth_assistant/model/user_config'
4
+
5
+ module ActiveRecord
6
+ module Generators
7
+ class RolesMigrationGenerator < Rails::Generators::NamedBase
8
+ include Rails::Generators::MigrationHelper
9
+ include RSpec::Rails::App
10
+
11
+ desc "Generates user role migrations"
12
+
13
+ # name is the user model to generate roles for
14
+
15
+ class_option :strategy, :type => :string, :aliases => "-s", :default => 'inline_role',
16
+ :desc => "Role strategy to use (admin_flag, role_string, one_role, many_roles, roles_mask)"
17
+
18
+ class_option :reverse, :type => :boolean, :alias => "-r", :default => false, :desc => "Create a remove migration for reversing a strategy"
19
+
20
+ def self.source_root
21
+ @source_root ||= File.expand_path("../templates", __FILE__)
22
+ end
23
+
24
+ def valid_strategy?
25
+ if ![:admin_flag, :role_string, :one_role, :many_roles, :roles_mask].include?(strategy.to_sym)
26
+ info "Unknown role strategy #{strategy}"
27
+ raise ArgumentError, "Unknown role strategy #{strategy}"
28
+ end
29
+ end
30
+
31
+ def run_migration
32
+ migration_name = "add_#{strategy}_strategy"
33
+ target_migration_name = reverse? ? reverse_migration_name(migration_name) : migration_name
34
+ migration_template "#{migration_name}.erb", "db/migrations/#{target_migration_name}"
35
+ generated_migration = latest_migration_file(migration_dir, target_migration_name)
36
+ reverse_migration!(generated_migration) if generated_migration && reverse?
37
+ end
38
+
39
+ protected
40
+
41
+ def reverse?
42
+ options[:reverse]
43
+ end
44
+
45
+ def table_name
46
+ name.tableize
47
+ end
48
+
49
+ def strategy
50
+ options[:strategy]
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,14 @@
1
+ class AddAdminFlagStrategy < ActiveRecord::Migration
2
+
3
+ def self.up
4
+ change_table :<%= table_name %> do |t|
5
+ t.boolean :admin_flag, :default => false
6
+ end
7
+ end
8
+
9
+ def self.down
10
+ change_table :<%= table_name %> do |t|
11
+ t.remove :admin_flag
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,40 @@
1
+ class AddManyRolesStrategy < ActiveRecord::Migration
2
+ class << self
3
+
4
+ def up
5
+ create_roles
6
+ create_user_roles
7
+ end
8
+
9
+ def down
10
+ drop_roles
11
+ drop_user_roles
12
+ end
13
+
14
+ protected
15
+
16
+ def create_user_roles
17
+ create_table :<%= table_name.singularize %>_roles do |t|
18
+ t.integer :<%= table_name.singularize %>_id
19
+ t.integer :role_id
20
+ t.timestamps
21
+ end
22
+ end
23
+
24
+ def drop_user_roles
25
+ drop_table :<%= table_name.singularize %>_roles
26
+ end
27
+
28
+
29
+ def create_roles
30
+ create_table :roles do |t|
31
+ t.string :name
32
+ t.timestamps
33
+ end
34
+ end
35
+
36
+ def drop_roles
37
+ drop_table :roles
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,40 @@
1
+ class AddOneRoleStrategy < ActiveRecord::Migration
2
+ class << self
3
+
4
+ def up
5
+ create_roles
6
+ add_user_role
7
+ end
8
+
9
+ def down
10
+ drop_roles
11
+ remove_user_role
12
+ end
13
+
14
+ protected
15
+
16
+ def add_user_role
17
+ change_table :<%= table_name %> do |t|
18
+ t.integer :role_id
19
+ end
20
+ end
21
+
22
+ def remove_user_role
23
+ change_table :<%= table_name %> do |t|
24
+ t.remove :role_id
25
+ end
26
+ end
27
+
28
+
29
+ def create_roles
30
+ create_table :roles do |t|
31
+ t.string :name
32
+ t.timestamps
33
+ end
34
+ end
35
+
36
+ def drop_roles
37
+ drop_table :roles
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,13 @@
1
+ class AddRoleStringStrategy < ActiveRecord::Migration
2
+ def self.up
3
+ change_table :<%= table_name %> do |t|
4
+ t.string :role, :default => 'guest'
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ change_table :<%= table_name %> do |t|
10
+ t.remove :role
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class AddRolesMaskStrategy < ActiveRecord::Migration
2
+ def self.up
3
+ change_table :<%= table_name %> do |t|
4
+ t.integer :roles_mask, :default => 1
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ change_table :<%= table_name %> do |t|
10
+ t.remove :roles_mask
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,40 @@
1
+ require 'generators/migration_helper'
2
+ require 'generators/role_migrations'
3
+ require 'auth_assistant/model/user_config'
4
+
5
+ module AuthAssistant
6
+ module Generators
7
+ class SetupGenerator < Rails::Generators::NamedBase
8
+ desc "Sets up Devise Users and creates Role migrations"
9
+
10
+ class_option :devise, :type => :boolean, :aliases => "-d", :default => false,
11
+ :desc => "Initialize devise."
12
+
13
+ class_option :admin, :type => :boolean, :aliases => "-a", :default => false,
14
+ :desc => "Create admin user."
15
+
16
+
17
+ class_option :migration, :type => :boolean, :aliases => "-m", :default => true,
18
+ :desc => "To generate a user role migration."
19
+
20
+ hook_for :orm
21
+
22
+ def self.source_root
23
+ @source_root ||= File.expand_path("../../templates", __FILE__)
24
+ end
25
+
26
+ def run_migration
27
+ clear_relations :user
28
+ return nil if !options[:migration]
29
+ clazz = AuthAssist::RoleMigrations.clazz(name)
30
+ mig_obj = clazz.new(self)
31
+ mig_obj.run_migration if mig_obj.respond_to? :run_migration
32
+ mig_obj.configure if mig_obj.respond_to? :configure
33
+ end
34
+
35
+ protected
36
+ include ::AuthAssist::MigrationHelper
37
+ include ::AuthAssist::RoleMigrations
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,19 @@
1
+ module Roles::Base
2
+ def valid_roles_are(*role_list)
3
+ strategy_class.valid_roles = role_list.to_symbols
4
+ end
5
+ end
6
+
7
+ module Roles::ActiveRecord
8
+ def self.included(base)
9
+ base.extend Roles::Base
10
+ base.extend ClassMethods
11
+ base.orm_name = :active_record
12
+ end
13
+
14
+ module ClassMethods
15
+ def strategy name, options=nil
16
+ role_strategy name, options
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ require 'sugar-high/module'
2
+
3
+ module Roles
4
+ modules :active_record do
5
+ nested_modules :user, :role
6
+ end
7
+ modules :base, :strategy
8
+ end
9
+
10
+ module RoleStrategy
11
+ modules :active_record
12
+ end
@@ -0,0 +1,24 @@
1
+ module Roles::Base
2
+ def valid_roles_are(*role_list)
3
+ strategy_class.valid_roles = role_list.to_symbols
4
+ if role_class_name
5
+ role_list.each do |name|
6
+ res = role_class_name.create(:name => name.to_s)
7
+ end
8
+ end
9
+ end
10
+ end
11
+
12
+ class Role < ActiveRecord::Base
13
+ class << self
14
+ def find_roles(*role_names)
15
+ where(:name.in => role_names.flatten)
16
+ end
17
+
18
+ def find_role role_name
19
+ raise ArgumentError, "#find_role takes a single role name as argument, not: #{role_name.inspect}" if !role_name.kind_of_label?
20
+ res = find_roles(role_name)
21
+ res ? res.first : res
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,70 @@
1
+ class Role < ActiveRecord::Base
2
+ scope :named, lambda{|role_names| where(:name.in => role_names.flatten)}
3
+ has_many :users, :through => :user_roles
4
+ has_many :user_roles
5
+ end
6
+
7
+ class UserRole < ActiveRecord::Base
8
+ belongs_to :user
9
+ belongs_to :role
10
+ end
11
+
12
+ module RoleStrategy::ActiveRecord
13
+ module ManyRoles
14
+ def self.default_role_attribute
15
+ :many_roles
16
+ end
17
+
18
+ def self.included base
19
+ base.extend Roles::Generic::Role::ClassMethods
20
+ base.extend ClassMethods
21
+ base.has_many :many_roles, :through => :user_roles, :source => :role
22
+ base.has_many :user_roles
23
+ end
24
+
25
+ module ClassMethods
26
+ def in_role(role_name)
27
+ in_roles(role_name)
28
+ end
29
+
30
+ def in_roles(*role_names)
31
+ joins(:many_roles) & Role.named(role_names)
32
+ end
33
+ end
34
+
35
+ module Implementation
36
+ def role_attribute
37
+ strategy_class.roles_attribute_name
38
+ end
39
+
40
+ # assign roles
41
+ def roles=(*roles)
42
+ raise "Role class #{role_class} does not have a #find_role(role) method" if !role_class.respond_to? :find_role
43
+ role_relations = role_class.find_roles(*roles)
44
+ self.send("#{role_attribute}=", role_relations)
45
+ save
46
+ end
47
+
48
+ def add_roles(*roles)
49
+ raise "Role class #{role_class} does not have a #find_role(role) method" if !role_class.respond_to? :find_role
50
+ role_relations = role_class.find_roles(*roles)
51
+ puts "role_relations: #{role_relations.inspect}"
52
+ self.send(role_attribute) << role_relations
53
+ save
54
+ end
55
+
56
+ # query assigned roles
57
+ def roles
58
+ self.send(role_attribute)
59
+ end
60
+
61
+ def roles_list
62
+ [roles].flatten.map{|r| r.name }.compact.to_symbols
63
+ end
64
+ end
65
+
66
+ extend Roles::Generic::User::Configuration
67
+ configure :type => :role_class
68
+ end
69
+ end
70
+