troles 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.textile +75 -16
- data/VERSION +1 -1
- data/lib/trole/adapters/active_record/config.rb +3 -3
- data/lib/trole/adapters/mongoid/config.rb +5 -5
- data/lib/trole/config.rb +2 -2
- data/lib/trole_groups.rb +10 -0
- data/lib/trole_groups/READ THIS.textile +4 -0
- data/lib/trole_groups/Rolegroups design.textile +218 -0
- data/lib/trole_groups/adapters/active_record.rb +8 -0
- data/lib/trole_groups/adapters/active_record/config.rb +0 -0
- data/lib/trole_groups/adapters/active_record/storage.rb +0 -0
- data/lib/trole_groups/adapters/active_record/strategy.rb +11 -0
- data/lib/trole_groups/adapters/mongoid.rb +8 -0
- data/lib/trole_groups/adapters/mongoid/config.rb +0 -0
- data/lib/trole_groups/api.rb +29 -0
- data/lib/trole_groups/api/cache.rb +13 -0
- data/lib/trole_groups/api/config.rb +4 -0
- data/lib/trole_groups/api/core.rb +50 -0
- data/lib/trole_groups/api/event.rb +29 -0
- data/lib/trole_groups/api/read.rb +56 -0
- data/lib/trole_groups/api/validation.rb +44 -0
- data/lib/trole_groups/api/write.rb +60 -0
- data/lib/trole_groups/config.rb +134 -0
- data/lib/trole_groups/config/schema.rb +65 -0
- data/lib/trole_groups/config/schema/helpers.rb +11 -0
- data/lib/trole_groups/config/schema/role_group_helpers.rb +11 -0
- data/lib/trole_groups/config/valid_role_groups.rb +21 -0
- data/lib/trole_groups/macros.rb +42 -0
- data/lib/trole_groups/macros/configuration.rb +89 -0
- data/lib/trole_groups/macros/configuration/base_loader.rb +35 -0
- data/lib/trole_groups/macros/configuration/config_loader.rb +19 -0
- data/lib/trole_groups/macros/configuration/storage_loader.rb +20 -0
- data/lib/trole_groups/macros/configuration/strategy_loader.rb +38 -0
- data/lib/trole_groups/macros/static_roles.rb +9 -0
- data/lib/trole_groups/macros/strategy_options.rb +21 -0
- data/lib/trole_groups/operations.rb +25 -0
- data/lib/trole_groups/operations/read.rb +36 -0
- data/lib/trole_groups/operations/write.rb +42 -0
- data/lib/trole_groups/storage.rb +27 -0
- data/lib/trole_groups/storage/base_many.rb +93 -0
- data/lib/trole_groups/storage/embed_many.rb +58 -0
- data/lib/trole_groups/storage/ref_many.rb +47 -0
- data/lib/trole_groups/strategy.rb +30 -0
- data/lib/troles/adapters/active_record/config.rb +32 -9
- data/lib/troles/adapters/mongoid/config.rb +7 -7
- data/lib/troles/common/api/core.rb +1 -1
- data/lib/troles/common/config.rb +49 -14
- data/lib/troles/common/config/schema.rb +17 -23
- data/lib/troles/common/config/schema/helpers.rb +77 -0
- data/lib/troles/common/config/schema/role_helpers.rb +27 -0
- data/lib/troles/common/config/static_roles.rb +4 -4
- data/lib/troles/common/macros.rb +4 -4
- data/lib/troles/common/macros/configuration.rb +8 -8
- data/lib/troles/common/macros/strategy_options.rb +4 -4
- data/lib/troles/common/storage.rb +1 -0
- data/lib/troles/config.rb +2 -2
- data/lib/troles/storage/ref_many.rb +2 -3
- data/spec/active_record/models/ref_many.rb +3 -0
- data/spec/active_record/strategies/many/ref_many_spec.rb +2 -1
- data/spec/generic/models/role.rb +2 -1
- data/spec/trole_groups/api/core_api_spec.rb +14 -0
- data/spec/trole_groups/api/read_api_spec.rb +36 -0
- data/spec/trole_groups/api/write_api_spec.rb +19 -0
- data/spec/trole_groups/api_spec.rb +27 -0
- data/spec/trole_groups/generic/models.rb +3 -0
- data/spec/trole_groups/generic/models/role_group.rb +44 -0
- data/spec/trole_groups/generic/models/user.rb +9 -0
- data/spec/trole_groups/strategies/ref_many.rb +51 -0
- data/spec/trole_groups/strategy_helper.rb +9 -0
- data/spec/trole_groups_spec.rb +11 -0
- data/spec/trole_spec_helper.rb +9 -0
- data/spec/troles/api_spec.rb +12 -18
- data/troles.gemspec +52 -4
- metadata +85 -37
- data/development.sqlite3 +0 -0
- data/lib/troles/common/config/schema_helpers.rb +0 -95
@@ -0,0 +1,8 @@
|
|
1
|
+
module TroleGroups
|
2
|
+
module ActiveRecord
|
3
|
+
autoload :Config, 'trole_groups/adapters/active_record/config'
|
4
|
+
# autoload :Api, 'trole_groups/adapters/active_record/api'
|
5
|
+
autoload :Storage, 'trole_groups/adapters/active_record/storage'
|
6
|
+
autoload :Strategy, 'trole_groups/adapters/active_record/strategy'
|
7
|
+
end
|
8
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module TroleGroups::ActiveRecord
|
2
|
+
module Strategy
|
3
|
+
module BaseMany
|
4
|
+
# @param [Class] the role subject class for which to include the Role strategy (fx User Account)
|
5
|
+
#
|
6
|
+
def self.included(base)
|
7
|
+
base.send :include, TroleGroups::Strategy::BaseMany
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module TroleGroups
|
2
|
+
module Mongoid
|
3
|
+
autoload :Config, 'trole_groups/adapters/mongoid/config'
|
4
|
+
# autoload :Api, 'trole_groups/adapters/mongoid/api'
|
5
|
+
# autoload :Storage, 'trole_groups/adapters/mongoid/storage'
|
6
|
+
# autoload :Strategy, 'trole_groups/adapters/mongoid/strategy'
|
7
|
+
end
|
8
|
+
end
|
File without changes
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module TroleGroups
|
2
|
+
module Api
|
3
|
+
autoload :Core, 'trole_groups/api/core'
|
4
|
+
autoload :Cache, 'trole_groups/api/cache'
|
5
|
+
autoload :Config, 'trole_groups/api/config'
|
6
|
+
autoload :Event, 'trole_groups/api/event'
|
7
|
+
autoload :Read, 'trole_groups/api/read'
|
8
|
+
autoload :Write, 'trole_groups/api/write'
|
9
|
+
autoload :Validation, 'trole_groups/api/validation'
|
10
|
+
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def apis
|
14
|
+
[:core, :cache, :config, :event, :read, :validation, :write]
|
15
|
+
end
|
16
|
+
|
17
|
+
def included(base)
|
18
|
+
apis.each do |api|
|
19
|
+
begin
|
20
|
+
base.include_and_extend :"#{api.to_s.camelize}"
|
21
|
+
rescue
|
22
|
+
puts "include error: #{api}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
extend ClassMethods
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#
|
2
|
+
# @author Kristian Mandrup
|
3
|
+
#
|
4
|
+
# Caching Api to ensure the rolegroup list of a rolegroup subject is cached and invalidated on rolegroup change
|
5
|
+
#
|
6
|
+
module TroleGroups::Api
|
7
|
+
module Cache
|
8
|
+
def invalidate_rolegroups_cache!
|
9
|
+
@rolegroup_list = nil
|
10
|
+
invalidate_role_cache!
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module TroleGroups::Api
|
2
|
+
module Core
|
3
|
+
# Access to the Troles operations API
|
4
|
+
# @return [Troles::Operations] the operations API object
|
5
|
+
def rolegroups
|
6
|
+
@rolegroups ||= TroleGroups::Operations.new(self)
|
7
|
+
end
|
8
|
+
|
9
|
+
# Sets the roles of the subject
|
10
|
+
# (see #set_roles)
|
11
|
+
def rolegroups= *new_rolegroups
|
12
|
+
rolegroups.set_rolegroups new_rolegroups
|
13
|
+
end
|
14
|
+
|
15
|
+
# If this role subject instance should have static (immutable) roles
|
16
|
+
# @return [true, false] defaults to false so a role subject is allowed to change roles
|
17
|
+
def static_roles?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
def trolegroups_config
|
22
|
+
self.class.trolegroups_config
|
23
|
+
end
|
24
|
+
|
25
|
+
module ClassMethods
|
26
|
+
|
27
|
+
def rolegroup_field
|
28
|
+
trolegroups_config.rolegroup_field
|
29
|
+
end
|
30
|
+
|
31
|
+
def valid_rolegroups
|
32
|
+
trolegroups_config.valid_roles
|
33
|
+
end
|
34
|
+
|
35
|
+
# # TODO: make sure alphanumeric only
|
36
|
+
# def valid_roles= *roles
|
37
|
+
# troles_config.valid_roles = *roles
|
38
|
+
# end
|
39
|
+
|
40
|
+
# If all role subjects using this strategy should have static (immutable) roles
|
41
|
+
#
|
42
|
+
# @note Should also proxy Config object?
|
43
|
+
#
|
44
|
+
# @return [true, false] if role subjects have static roles or not (default: false)
|
45
|
+
def static_roles?
|
46
|
+
false # trolegroups_config.static_roles?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module TroleGroups::Api
|
2
|
+
module Event
|
3
|
+
# a change to the roles of the user should be published to an event handler
|
4
|
+
# this can be used to update both the Role cache of the user and fx the RolePermit cache.
|
5
|
+
# Both (and potentially others, fx for Role Groups) can subscribe to this event!
|
6
|
+
def update_role_groups
|
7
|
+
publish_change(:role_groups) if field_changed?(rolegroups_field)
|
8
|
+
end
|
9
|
+
|
10
|
+
# check if a field on the model changed
|
11
|
+
# See http://api.rubyonrails.org/classes/ActiveModel/Dirty.html
|
12
|
+
def field_changed? name
|
13
|
+
send :"#{name}_changed?"
|
14
|
+
end
|
15
|
+
|
16
|
+
# can be customized
|
17
|
+
# here uses singleton EventManager
|
18
|
+
def publish_change event
|
19
|
+
send :invalidate_rolegroups_cache! if event == :role_groups
|
20
|
+
event_manager.publish_change event, :from => self
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def event_manager
|
26
|
+
Troles::Common::EventManager
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module TroleGroups::Api
|
2
|
+
module Read
|
3
|
+
def roles_from_rolegroups
|
4
|
+
group_store.display_roles
|
5
|
+
end
|
6
|
+
|
7
|
+
def roles_for *names
|
8
|
+
group_store.display_roles_for *names
|
9
|
+
end
|
10
|
+
|
11
|
+
# any? on rolegroups_list
|
12
|
+
def in_rolegroup? rolegroup
|
13
|
+
rolegroup_list.include? rolegroup.to_sym
|
14
|
+
end
|
15
|
+
alias_method :has_rolegroup?, :in_rolegroup?
|
16
|
+
|
17
|
+
# rolegroup_list has one element which is rolegroup
|
18
|
+
def only_in_rolegroup? rolegroup
|
19
|
+
rolegroup_list.first == rolegroup.to_sym && rolegroup_list.size == 1
|
20
|
+
end
|
21
|
+
|
22
|
+
# subtraction of role_groups from rolegroups_list is empty
|
23
|
+
def in_rolegroups? *rolegroups
|
24
|
+
(rolegroups.to_symbols - rolegroup_list).empty?
|
25
|
+
end
|
26
|
+
alias_method :has_rolegroups?, :in_rolegroups?
|
27
|
+
|
28
|
+
# union of rolegroups and rolegroups_list is not empty
|
29
|
+
def in_any_rolegroup? *rolegroups
|
30
|
+
!(rolegroup_list & rolegroups.to_symbols).empty?
|
31
|
+
end
|
32
|
+
alias_method :has_any_rolegroup?, :in_any_rolegroup?
|
33
|
+
|
34
|
+
# return roles of that rolegroup
|
35
|
+
def roles_of rolegroup
|
36
|
+
raise "Pending"
|
37
|
+
end
|
38
|
+
|
39
|
+
# return Set of symbols,where each symbol is a rolegroup name
|
40
|
+
# This set should be cached and only invalidated when the user has a change of roles
|
41
|
+
def rolegroup_list
|
42
|
+
@rolegroup_list ||= begin
|
43
|
+
group_store.display_rolegroups
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Ensures that the common API methods always have a common underlying model to work on
|
48
|
+
# @note This Set should be cached and only invalidated when the user has a change of roles
|
49
|
+
# @return Array<Symbol> Set of role names
|
50
|
+
def role_list
|
51
|
+
@role_list ||= begin
|
52
|
+
(store.display_roles | group_store.display_roles)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#
|
2
|
+
# @author Kristian Mandrup
|
3
|
+
#
|
4
|
+
# Common Validation API
|
5
|
+
#
|
6
|
+
module TroleGroups::Api
|
7
|
+
module Validation
|
8
|
+
|
9
|
+
# @return [Symbol, false] returns the role if it's valid, false if not
|
10
|
+
def check_valid_rolegroup? rolegroup
|
11
|
+
return rolegroup if valid_rolegroups.include? rolegroup.to_sym
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Array<Symbol>] returns the valid roles or empty list if no valid roles
|
16
|
+
def check_valid_rolegroups? *rolegroups
|
17
|
+
valid_rolegroups & rolegroups.to_symbols
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
# Ensures the role is valid
|
23
|
+
# @param [Symbol] role name
|
24
|
+
# @return [Symbol, false, Error] a valid role name, false if invalid, or Error on some error
|
25
|
+
def make_valid_rolegroup rolegroup
|
26
|
+
raise ArgumentError, "Rolegroup to set must be a Symbol or String" if !rolegroup.kind_of_label?
|
27
|
+
check_valid_rolegroup? rolegroup.to_s.alpha_numeric
|
28
|
+
end
|
29
|
+
|
30
|
+
# Ensures the role are valid
|
31
|
+
# @param [Symbol] list of roles
|
32
|
+
# @return [Array<Symbol>] the valid roles from the list of roles given
|
33
|
+
def make_valid_rolegroups *rolegroups
|
34
|
+
rolegroups = rolegroups.to_symbols_uniq
|
35
|
+
return [] if rolegroups.empty?
|
36
|
+
check_valid_rolegroups? rolegroups.map{|r| r.to_s.alpha_numeric}
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Array<Symbol>] the valid roles of the role subject
|
40
|
+
def valid_rolegroups
|
41
|
+
self.class.trolegroups_config.valid_rolegroups
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module TroleGroups::Api
|
2
|
+
module Write
|
3
|
+
# Add a single new rolegroup to the rolegroups of the subject
|
4
|
+
# @param [Symbol] rolegroup to add
|
5
|
+
# @return (see #add_rolegroups)
|
6
|
+
def add_rolegroup rolegroup_name
|
7
|
+
raise ArgumentError, "Take a single rolegroup name, was: #{rolegroup_name}" if !rolegroup_name || !rolegroup_name.kind_of_label?
|
8
|
+
add_rolegroups rolegroup_name
|
9
|
+
end
|
10
|
+
|
11
|
+
# Remove a single rolegroup from the rolegroups of the subject
|
12
|
+
# @param [Symbol] rolegroup to remove
|
13
|
+
# @return (see #remove_rolegroups)
|
14
|
+
def remove_rolegroup rolegroup_name
|
15
|
+
raise ArgumentError, "Take a single rolegroup name, was: #{rolegroup_name}" if !rolegroup_name || !rolegroup_name.kind_of_label?
|
16
|
+
remove_rolegroups rolegroup_name
|
17
|
+
end
|
18
|
+
|
19
|
+
# Adds a set of new rolegroups to the rolegroups of the subject
|
20
|
+
# @param [Array<Symbol>] list of rolegroups to add
|
21
|
+
# @return [true, false, Error] true if ok, false if static or invalid, Error on some error
|
22
|
+
def add_rolegroups *new_rolegroups
|
23
|
+
group_store.set_rolegroups (rolegroup_list | new_rolegroups.to_symbols_uniq) # Set Union (joined set)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Removes a set of new rolegroups to the rolegroups of the subject
|
27
|
+
# (see #add_rolegroups)
|
28
|
+
def remove_rolegroups *the_rolegroups
|
29
|
+
group_store.set_rolegroups (rolegroup_list - the_rolegroups.to_symbols_uniq)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Sets new rolegroups for the subject
|
33
|
+
# @param [Array<Symbol>] list of rolegroup names
|
34
|
+
# @return [true, false, Error] true if set ok, false if any rolegroups were invalid, Error on some error
|
35
|
+
def set_rolegroups *rolegroups
|
36
|
+
rolegroups_to_set = make_valid_rolegroups(*rolegroups).flat_uniq
|
37
|
+
return false if !rolegroups_to_set || rolegroups_to_set.empty?
|
38
|
+
group_store.set_rolegroups(rolegroups_to_set)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Clears all the rolegroups of the subject
|
42
|
+
# @return [true, false, Error] true if ok, false if rolegroups are static, Error on some error
|
43
|
+
def clear_rolegroups!
|
44
|
+
group_store.clear!
|
45
|
+
end
|
46
|
+
|
47
|
+
module ClassMethods
|
48
|
+
# Sets which rolegroups are valid for the rolegroup subject class (fx User or UserAccount)
|
49
|
+
#
|
50
|
+
# @note this in effect limits what rolegroups can be assigned to any instance of the class
|
51
|
+
#
|
52
|
+
# @param [Array<Symbol>] list of rolegroup names
|
53
|
+
def set_valid_rolegroups *rolegroups
|
54
|
+
rolegroups = rolegroups.to_symbols_uniq
|
55
|
+
raise ArgumentError, "Roles must contain Symbols or Strings" if rolegroups.empty?
|
56
|
+
@valid_rolegroups = rolegroups
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module TroleGroups
|
2
|
+
class Config
|
3
|
+
autoload :ValidRoleGroups, 'trole_groups/config/valid_role_groups'
|
4
|
+
autoload :Schema, 'trole_groups/config/schema'
|
5
|
+
|
6
|
+
def self.sub_modules
|
7
|
+
[:valid_role_groups, :schema] # , :static_roles, ,
|
8
|
+
end
|
9
|
+
|
10
|
+
sub_modules.each do |name|
|
11
|
+
begin
|
12
|
+
self.send :include, "TroleGroups::Config::#{name.to_s.camelize}".constantize
|
13
|
+
rescue Error => e
|
14
|
+
puts "include sub-module #{name}, error: #{e}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_accessor :subject_class, :strategy, :log_on, :generic, :auto_relations
|
19
|
+
attr_writer :orm
|
20
|
+
|
21
|
+
def initialize subject_class, options = {}
|
22
|
+
@subject_class = subject_class
|
23
|
+
# set instance var for each pair in options
|
24
|
+
apply_options! options
|
25
|
+
end
|
26
|
+
|
27
|
+
def apply_options! options = {}
|
28
|
+
options.each_pair do |key, value|
|
29
|
+
send("#{key}=", value) if self.respond_to?(:"#{key}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def configure! options = {}
|
34
|
+
apply_options! options
|
35
|
+
configure_models if auto_config?(:models)
|
36
|
+
end
|
37
|
+
|
38
|
+
class << self
|
39
|
+
attr_reader :default_orm, :auto_load
|
40
|
+
attr_accessor :log_on
|
41
|
+
|
42
|
+
def log_on?
|
43
|
+
log_on || false
|
44
|
+
end
|
45
|
+
|
46
|
+
def default_orm= orm
|
47
|
+
@default_orm ||= orm
|
48
|
+
end
|
49
|
+
|
50
|
+
def auto_load= mode
|
51
|
+
raise "Autoload must be set to true or false" if ![true, false].include? mode
|
52
|
+
@auto_load = mode
|
53
|
+
end
|
54
|
+
|
55
|
+
def auto_load?
|
56
|
+
@auto_load
|
57
|
+
end
|
58
|
+
|
59
|
+
def auto_config
|
60
|
+
auto_config_setings
|
61
|
+
end
|
62
|
+
|
63
|
+
def auto_config? name
|
64
|
+
auto_config_setings[name]
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
|
69
|
+
|
70
|
+
def auto_config_setings
|
71
|
+
@auto_config_setings ||= auto_config_defaults
|
72
|
+
end
|
73
|
+
|
74
|
+
# default auto_config settings
|
75
|
+
def auto_config_defaults
|
76
|
+
{:models => true, :relations => true, :fields => true}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def log_on?
|
81
|
+
log_on || Troles::Config.log_on
|
82
|
+
end
|
83
|
+
|
84
|
+
def auto_config
|
85
|
+
auto_config_setings
|
86
|
+
end
|
87
|
+
|
88
|
+
def auto_config? name
|
89
|
+
return auto_config_setings[name] if !auto_config_setings[name].nil?
|
90
|
+
Troles::Config.auto_config?(name)
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
def auto_config_setings
|
95
|
+
@auto_config_setings ||= {}
|
96
|
+
end
|
97
|
+
|
98
|
+
def role_field
|
99
|
+
@role_field ||= begin
|
100
|
+
default_role_field
|
101
|
+
end
|
102
|
+
end
|
103
|
+
alias_method :rolegroup_field, :role_field
|
104
|
+
|
105
|
+
def role_field= field_name
|
106
|
+
name = field_name.to_s.alpha_numeric.to_sym
|
107
|
+
raise ArgumentException, "Not a valid role field name: #{field_name}" if !valid_field_name?(name)
|
108
|
+
@role_field ||= name
|
109
|
+
end
|
110
|
+
alias_method :rolegroup_field=, :role_field=
|
111
|
+
|
112
|
+
def default_role_field
|
113
|
+
:trole_groups
|
114
|
+
end
|
115
|
+
|
116
|
+
def orm
|
117
|
+
@orm || self.class.default_orm
|
118
|
+
end
|
119
|
+
|
120
|
+
def singularity
|
121
|
+
@singularity ||= (strategy =~ /_many$/) ? :many : :one
|
122
|
+
end
|
123
|
+
|
124
|
+
# def singularity= value
|
125
|
+
# raise ArgumentError, "Must be :many or :one" if ![:one, :many].include?(value)
|
126
|
+
# @singularity ||= value
|
127
|
+
# end
|
128
|
+
|
129
|
+
def generic?
|
130
|
+
return true if orm.nil?
|
131
|
+
@generic.nil? ? false : @generic
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|