roles_active_record 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+