mongo_mapper-rails3 0.7.0.1 → 0.7.2
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.
- data/README.rdoc +8 -37
- metadata +16 -284
- data/.gitignore +0 -10
- data/Gemfile +0 -15
- data/LICENSE +0 -20
- data/Rakefile +0 -58
- data/VERSION +0 -1
- data/bin/mmconsole +0 -60
- data/lib/mongo_mapper.rb +0 -131
- data/lib/mongo_mapper/document.rb +0 -439
- data/lib/mongo_mapper/embedded_document.rb +0 -68
- data/lib/mongo_mapper/plugins.rb +0 -30
- data/lib/mongo_mapper/plugins/associations.rb +0 -106
- data/lib/mongo_mapper/plugins/associations/base.rb +0 -123
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +0 -30
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +0 -25
- data/lib/mongo_mapper/plugins/associations/collection.rb +0 -21
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +0 -50
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +0 -141
- data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +0 -28
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +0 -120
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +0 -31
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +0 -23
- data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +0 -13
- data/lib/mongo_mapper/plugins/associations/one_proxy.rb +0 -68
- data/lib/mongo_mapper/plugins/associations/proxy.rb +0 -119
- data/lib/mongo_mapper/plugins/callbacks.rb +0 -87
- data/lib/mongo_mapper/plugins/clone.rb +0 -14
- data/lib/mongo_mapper/plugins/descendants.rb +0 -17
- data/lib/mongo_mapper/plugins/dirty.rb +0 -120
- data/lib/mongo_mapper/plugins/equality.rb +0 -24
- data/lib/mongo_mapper/plugins/identity_map.rb +0 -124
- data/lib/mongo_mapper/plugins/inspect.rb +0 -15
- data/lib/mongo_mapper/plugins/keys.rb +0 -310
- data/lib/mongo_mapper/plugins/logger.rb +0 -19
- data/lib/mongo_mapper/plugins/pagination.rb +0 -26
- data/lib/mongo_mapper/plugins/pagination/proxy.rb +0 -72
- data/lib/mongo_mapper/plugins/protected.rb +0 -46
- data/lib/mongo_mapper/plugins/rails.rb +0 -46
- data/lib/mongo_mapper/plugins/serialization.rb +0 -50
- data/lib/mongo_mapper/plugins/validations.rb +0 -88
- data/lib/mongo_mapper/query.rb +0 -130
- data/lib/mongo_mapper/support.rb +0 -217
- data/lib/mongo_mapper/support/descendant_appends.rb +0 -46
- data/lib/mongo_mapper/support/find.rb +0 -77
- data/mongo_mapper-rails3.gemspec +0 -208
- data/performance/read_write.rb +0 -52
- data/specs.watchr +0 -51
- data/test/NOTE_ON_TESTING +0 -1
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +0 -63
- data/test/functional/associations/test_belongs_to_proxy.rb +0 -101
- data/test/functional/associations/test_in_array_proxy.rb +0 -321
- data/test/functional/associations/test_many_documents_as_proxy.rb +0 -229
- data/test/functional/associations/test_many_documents_proxy.rb +0 -453
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +0 -176
- data/test/functional/associations/test_many_embedded_proxy.rb +0 -256
- data/test/functional/associations/test_many_polymorphic_proxy.rb +0 -302
- data/test/functional/associations/test_one_proxy.rb +0 -161
- data/test/functional/test_associations.rb +0 -44
- data/test/functional/test_binary.rb +0 -27
- data/test/functional/test_callbacks.rb +0 -81
- data/test/functional/test_dirty.rb +0 -163
- data/test/functional/test_document.rb +0 -1244
- data/test/functional/test_embedded_document.rb +0 -125
- data/test/functional/test_identity_map.rb +0 -508
- data/test/functional/test_logger.rb +0 -20
- data/test/functional/test_modifiers.rb +0 -252
- data/test/functional/test_pagination.rb +0 -93
- data/test/functional/test_protected.rb +0 -161
- data/test/functional/test_string_id_compatibility.rb +0 -67
- data/test/functional/test_validations.rb +0 -329
- data/test/models.rb +0 -232
- data/test/support/custom_matchers.rb +0 -55
- data/test/support/timing.rb +0 -16
- data/test/test_helper.rb +0 -59
- data/test/unit/associations/test_base.rb +0 -207
- data/test/unit/associations/test_proxy.rb +0 -105
- data/test/unit/serializers/test_json_serializer.rb +0 -189
- data/test/unit/test_descendant_appends.rb +0 -71
- data/test/unit/test_document.rb +0 -231
- data/test/unit/test_dynamic_finder.rb +0 -123
- data/test/unit/test_embedded_document.rb +0 -663
- data/test/unit/test_keys.rb +0 -169
- data/test/unit/test_lint.rb +0 -8
- data/test/unit/test_mongo_mapper.rb +0 -125
- data/test/unit/test_pagination.rb +0 -160
- data/test/unit/test_plugins.rb +0 -51
- data/test/unit/test_query.rb +0 -334
- data/test/unit/test_rails.rb +0 -123
- data/test/unit/test_rails_compatibility.rb +0 -57
- data/test/unit/test_serialization.rb +0 -51
- data/test/unit/test_support.rb +0 -362
- data/test/unit/test_time_zones.rb +0 -39
- data/test/unit/test_validations.rb +0 -557
@@ -1,87 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Plugins
|
3
|
-
module Callbacks
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
included do
|
6
|
-
extend ActiveModel::Callbacks
|
7
|
-
|
8
|
-
# Define all the callbacks that are accepted by the document.
|
9
|
-
define_model_callbacks \
|
10
|
-
:create,
|
11
|
-
:destroy,
|
12
|
-
:save,
|
13
|
-
:update,
|
14
|
-
:terminator => false
|
15
|
-
|
16
|
-
define_callbacks :validation, :terminator => "result == false", :scope => [:kind, :name]
|
17
|
-
|
18
|
-
extend ValidationCallbacks
|
19
|
-
|
20
|
-
[:create_or_update, :valid?, :create, :update, :destroy].each do |method|
|
21
|
-
alias_method_chain method, :callbacks
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
module ValidationCallbacks
|
26
|
-
def before_validation(*args, &block)
|
27
|
-
options = args.extract_options!
|
28
|
-
options[:if] = Array(options[:if])
|
29
|
-
options[:if] << "@_on_validate == :#{options[:on]}" if options[:on]
|
30
|
-
set_callback(:validation, :before, *(args << options), &block)
|
31
|
-
end
|
32
|
-
|
33
|
-
def after_validation(*args, &block)
|
34
|
-
options = args.extract_options!
|
35
|
-
options[:prepend] = true
|
36
|
-
options[:if] = Array(options[:if])
|
37
|
-
options[:if] << "!halted && value != false"
|
38
|
-
options[:if] << "@_on_validate == :#{options[:on]}" if options[:on]
|
39
|
-
set_callback(:validation, :after, *(args << options), &block)
|
40
|
-
end
|
41
|
-
|
42
|
-
def before_validation_on_what(what, *args, &block)
|
43
|
-
options = args.extract_options!
|
44
|
-
options[:on] = what
|
45
|
-
before_validation(*(args << options), &block)
|
46
|
-
end
|
47
|
-
|
48
|
-
def before_validation_on_create(*args, &block); before_validation_on_what(:create, *args, &block); end
|
49
|
-
def before_validation_on_update(*args, &block); before_validation_on_what(:update, *args, &block); end
|
50
|
-
end
|
51
|
-
|
52
|
-
def create_or_update_with_callbacks(*args) #:nodoc:
|
53
|
-
_run_save_callbacks do
|
54
|
-
create_or_update_without_callbacks(*args)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
private :create_or_update_with_callbacks
|
58
|
-
|
59
|
-
def create_with_callbacks(*args) #:nodoc:
|
60
|
-
_run_create_callbacks do
|
61
|
-
create_without_callbacks(*args)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
private :create_with_callbacks
|
65
|
-
|
66
|
-
def update_with_callbacks(*args) #:nodoc:
|
67
|
-
_run_update_callbacks do
|
68
|
-
update_without_callbacks(*args)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
private :update_with_callbacks
|
72
|
-
|
73
|
-
def valid_with_callbacks? #:nodoc:
|
74
|
-
@_on_validate = new_record? ? :create : :update
|
75
|
-
_run_validation_callbacks do
|
76
|
-
valid_without_callbacks?
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def destroy_with_callbacks #:nodoc:
|
81
|
-
_run_destroy_callbacks do
|
82
|
-
destroy_without_callbacks
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Plugins
|
3
|
-
module Clone
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
module InstanceMethods
|
6
|
-
def clone
|
7
|
-
clone_attributes = self.attributes
|
8
|
-
clone_attributes.delete("_id")
|
9
|
-
self.class.new(clone_attributes)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Plugins
|
3
|
-
module Descendants
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
module ClassMethods
|
6
|
-
def inherited(descendant)
|
7
|
-
(@descendants ||= []) << descendant
|
8
|
-
super
|
9
|
-
end
|
10
|
-
|
11
|
-
def descendants
|
12
|
-
@descendants
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,120 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Plugins
|
3
|
-
module Dirty
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
module InstanceMethods
|
6
|
-
def method_missing(method, *args, &block)
|
7
|
-
if method.to_s =~ /(_changed\?|_change|_will_change!|_was)$/
|
8
|
-
method_suffix = $1
|
9
|
-
key = method.to_s.gsub(method_suffix, '')
|
10
|
-
|
11
|
-
if key_names.include?(key)
|
12
|
-
case method_suffix
|
13
|
-
when '_changed?'
|
14
|
-
key_changed?(key)
|
15
|
-
when '_change'
|
16
|
-
key_change(key)
|
17
|
-
when '_will_change!'
|
18
|
-
key_will_change!(key)
|
19
|
-
when '_was'
|
20
|
-
key_was(key)
|
21
|
-
end
|
22
|
-
else
|
23
|
-
super
|
24
|
-
end
|
25
|
-
else
|
26
|
-
super
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def changed?
|
31
|
-
!changed_keys.empty?
|
32
|
-
end
|
33
|
-
|
34
|
-
def changed
|
35
|
-
changed_keys.keys
|
36
|
-
end
|
37
|
-
|
38
|
-
def changes
|
39
|
-
changed.inject({}) { |h, key| h[key] = key_change(key); h }
|
40
|
-
end
|
41
|
-
|
42
|
-
def initialize(*args)
|
43
|
-
super
|
44
|
-
changed_keys.clear if args.first.blank? || !new?
|
45
|
-
end
|
46
|
-
|
47
|
-
def save(*args)
|
48
|
-
if status = super
|
49
|
-
changed_keys.clear
|
50
|
-
end
|
51
|
-
status
|
52
|
-
end
|
53
|
-
|
54
|
-
def save!(*args)
|
55
|
-
status = super
|
56
|
-
changed_keys.clear
|
57
|
-
status
|
58
|
-
end
|
59
|
-
|
60
|
-
def reload(*args)
|
61
|
-
document = super
|
62
|
-
changed_keys.clear
|
63
|
-
document
|
64
|
-
end
|
65
|
-
|
66
|
-
private
|
67
|
-
def clone_key_value(key)
|
68
|
-
value = read_key(key)
|
69
|
-
value.duplicable? ? value.clone : value
|
70
|
-
rescue TypeError, NoMethodError
|
71
|
-
value
|
72
|
-
end
|
73
|
-
|
74
|
-
def changed_keys
|
75
|
-
@changed_keys ||= {}
|
76
|
-
end
|
77
|
-
|
78
|
-
def key_changed?(key)
|
79
|
-
changed_keys.include?(key)
|
80
|
-
end
|
81
|
-
|
82
|
-
def key_change(key)
|
83
|
-
[changed_keys[key], __send__(key)] if key_changed?(key)
|
84
|
-
end
|
85
|
-
|
86
|
-
def key_was(key)
|
87
|
-
key_changed?(key) ? changed_keys[key] : __send__(key)
|
88
|
-
end
|
89
|
-
|
90
|
-
def key_will_change!(key)
|
91
|
-
changed_keys[key] = clone_key_value(key)
|
92
|
-
end
|
93
|
-
|
94
|
-
def write_key(key, value)
|
95
|
-
key = key.to_s
|
96
|
-
|
97
|
-
if changed_keys.include?(key)
|
98
|
-
old = changed_keys[key]
|
99
|
-
changed_keys.delete(key) unless value_changed?(key, old, value)
|
100
|
-
else
|
101
|
-
old = clone_key_value(key)
|
102
|
-
changed_keys[key] = old if value_changed?(key, old, value)
|
103
|
-
end
|
104
|
-
|
105
|
-
super(key, value)
|
106
|
-
end
|
107
|
-
|
108
|
-
def value_changed?(key_name, old, value)
|
109
|
-
key = keys[key_name]
|
110
|
-
|
111
|
-
if key.number? && value.blank?
|
112
|
-
value = nil
|
113
|
-
end
|
114
|
-
|
115
|
-
old != value
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Plugins
|
3
|
-
module Equality
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
module InstanceMethods
|
6
|
-
def ==(other)
|
7
|
-
other.is_a?(self.class) && _id == other._id
|
8
|
-
end
|
9
|
-
|
10
|
-
def eql?(other)
|
11
|
-
self == other
|
12
|
-
end
|
13
|
-
|
14
|
-
def equal?(other)
|
15
|
-
object_id === other.object_id
|
16
|
-
end
|
17
|
-
|
18
|
-
def hash
|
19
|
-
_id.hash
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,124 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Plugins
|
3
|
-
module IdentityMap
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
def self.models
|
7
|
-
@models ||= Set.new
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.clear
|
11
|
-
models.each { |m| m.identity_map.clear }
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.configure(model)
|
15
|
-
IdentityMap.models << model
|
16
|
-
end
|
17
|
-
|
18
|
-
module ClassMethods
|
19
|
-
def inherited(descendant)
|
20
|
-
descendant.identity_map = identity_map
|
21
|
-
super
|
22
|
-
end
|
23
|
-
|
24
|
-
def identity_map
|
25
|
-
@identity_map ||= {}
|
26
|
-
end
|
27
|
-
|
28
|
-
def identity_map=(v)
|
29
|
-
@identity_map = v
|
30
|
-
end
|
31
|
-
|
32
|
-
def find_one(options={})
|
33
|
-
criteria, query_options = to_query(options)
|
34
|
-
|
35
|
-
if simple_find?(criteria) && identity_map.key?(criteria[:_id])
|
36
|
-
identity_map[criteria[:_id]]
|
37
|
-
else
|
38
|
-
super.tap do |document|
|
39
|
-
remove_documents_from_map(document) if selecting_fields?(query_options)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def find_many(options)
|
45
|
-
criteria, query_options = to_query(options)
|
46
|
-
super.tap do |documents|
|
47
|
-
remove_documents_from_map(documents) if selecting_fields?(query_options)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def load(attrs)
|
52
|
-
document = identity_map[attrs['_id']]
|
53
|
-
|
54
|
-
if document.nil? || identity_map_off?
|
55
|
-
document = super
|
56
|
-
identity_map[document._id] = document if identity_map_on?
|
57
|
-
end
|
58
|
-
|
59
|
-
document
|
60
|
-
end
|
61
|
-
|
62
|
-
def identity_map_status
|
63
|
-
defined?(@identity_map_status) ? @identity_map_status : true
|
64
|
-
end
|
65
|
-
|
66
|
-
def identity_map_on
|
67
|
-
@identity_map_status = true
|
68
|
-
end
|
69
|
-
|
70
|
-
def identity_map_off
|
71
|
-
@identity_map_status = false
|
72
|
-
end
|
73
|
-
|
74
|
-
def identity_map_on?
|
75
|
-
identity_map_status
|
76
|
-
end
|
77
|
-
|
78
|
-
def identity_map_off?
|
79
|
-
!identity_map_on?
|
80
|
-
end
|
81
|
-
|
82
|
-
def without_identity_map(&block)
|
83
|
-
identity_map_off
|
84
|
-
yield
|
85
|
-
ensure
|
86
|
-
identity_map_on
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
def remove_documents_from_map(*documents)
|
91
|
-
documents.flatten.compact.each do |document|
|
92
|
-
identity_map.delete(document._id)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def simple_find?(criteria)
|
97
|
-
criteria.keys == [:_id] || criteria.keys.to_set == [:_id, :_type].to_set
|
98
|
-
end
|
99
|
-
|
100
|
-
def selecting_fields?(options)
|
101
|
-
!options[:fields].nil?
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
module InstanceMethods
|
106
|
-
def identity_map
|
107
|
-
self.class.identity_map
|
108
|
-
end
|
109
|
-
|
110
|
-
def save(*args)
|
111
|
-
if result = super
|
112
|
-
identity_map[_id] = self if self.class.identity_map_on?
|
113
|
-
end
|
114
|
-
result
|
115
|
-
end
|
116
|
-
|
117
|
-
def delete
|
118
|
-
identity_map.delete(_id) if self.class.identity_map_on?
|
119
|
-
super
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Plugins
|
3
|
-
module Inspect
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
module InstanceMethods
|
6
|
-
def inspect
|
7
|
-
attributes_as_nice_string = key_names.collect do |name|
|
8
|
-
"#{name}: #{self[name].inspect}"
|
9
|
-
end.join(", ")
|
10
|
-
"#<#{self.class} #{attributes_as_nice_string}>"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,310 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Plugins
|
3
|
-
module Keys
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
def self.configure(model)
|
7
|
-
model.key :_id, ObjectId
|
8
|
-
end
|
9
|
-
|
10
|
-
module ClassMethods
|
11
|
-
def inherited(descendant)
|
12
|
-
descendant.instance_variable_set(:@keys, keys.dup)
|
13
|
-
super
|
14
|
-
end
|
15
|
-
|
16
|
-
def keys
|
17
|
-
@keys ||= HashWithIndifferentAccess.new
|
18
|
-
end
|
19
|
-
|
20
|
-
def key(*args)
|
21
|
-
key = Key.new(*args)
|
22
|
-
keys[key.name] = key
|
23
|
-
|
24
|
-
create_accessors_for(key)
|
25
|
-
create_key_in_descendants(*args)
|
26
|
-
create_indexes_for(key)
|
27
|
-
create_validations_for(key)
|
28
|
-
|
29
|
-
key
|
30
|
-
end
|
31
|
-
|
32
|
-
def using_object_id?
|
33
|
-
object_id_key?(:_id)
|
34
|
-
end
|
35
|
-
|
36
|
-
def object_id_key?(name)
|
37
|
-
key = keys[name.to_s]
|
38
|
-
key && key.type == ObjectId
|
39
|
-
end
|
40
|
-
|
41
|
-
def to_mongo(instance)
|
42
|
-
return nil if instance.nil?
|
43
|
-
instance.to_mongo
|
44
|
-
end
|
45
|
-
|
46
|
-
def from_mongo(value)
|
47
|
-
return nil if value.nil?
|
48
|
-
value.is_a?(self) ? value : load(value)
|
49
|
-
end
|
50
|
-
|
51
|
-
# load is overridden in identity map to ensure same objects are loaded
|
52
|
-
def load(attrs)
|
53
|
-
begin
|
54
|
-
klass = attrs['_type'].present? ? attrs['_type'].constantize : self
|
55
|
-
klass.new(attrs, true)
|
56
|
-
rescue NameError
|
57
|
-
new(attrs, true)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
def accessors_module
|
63
|
-
module_defined = if method(:const_defined?).arity == 1 # Ruby 1.9 compat check
|
64
|
-
const_defined?('MongoMapperKeys')
|
65
|
-
else
|
66
|
-
const_defined?('MongoMapperKeys', false)
|
67
|
-
end
|
68
|
-
|
69
|
-
if module_defined
|
70
|
-
const_get 'MongoMapperKeys'
|
71
|
-
else
|
72
|
-
const_set 'MongoMapperKeys', Module.new
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def create_accessors_for(key)
|
77
|
-
accessors_module.module_eval <<-end_eval
|
78
|
-
def #{key.name}
|
79
|
-
read_key(:#{key.name})
|
80
|
-
end
|
81
|
-
|
82
|
-
def #{key.name}_before_typecast
|
83
|
-
read_key_before_typecast(:#{key.name})
|
84
|
-
end
|
85
|
-
|
86
|
-
def #{key.name}=(value)
|
87
|
-
write_key(:#{key.name}, value)
|
88
|
-
end
|
89
|
-
|
90
|
-
def #{key.name}?
|
91
|
-
read_key(:#{key.name}).present?
|
92
|
-
end
|
93
|
-
end_eval
|
94
|
-
|
95
|
-
include accessors_module
|
96
|
-
end
|
97
|
-
|
98
|
-
def create_key_in_descendants(*args)
|
99
|
-
return if descendants.blank?
|
100
|
-
descendants.each { |descendant| descendant.key(*args) }
|
101
|
-
end
|
102
|
-
|
103
|
-
def create_indexes_for(key)
|
104
|
-
ensure_index key.name if key.options[:index] && !key.embeddable?
|
105
|
-
end
|
106
|
-
|
107
|
-
def create_validations_for(key)
|
108
|
-
attribute = key.name.to_sym
|
109
|
-
|
110
|
-
if key.options[:required]
|
111
|
-
validates_presence_of(attribute)
|
112
|
-
end
|
113
|
-
|
114
|
-
if key.options[:unique]
|
115
|
-
validates_uniqueness_of(attribute)
|
116
|
-
end
|
117
|
-
|
118
|
-
if key.options[:numeric]
|
119
|
-
number_options = key.type == Integer ? {:only_integer => true} : {}
|
120
|
-
validates_numericality_of(attribute, number_options)
|
121
|
-
end
|
122
|
-
|
123
|
-
if key.options[:format]
|
124
|
-
validates_format_of(attribute, :with => key.options[:format])
|
125
|
-
end
|
126
|
-
|
127
|
-
if key.options[:in]
|
128
|
-
validates_inclusion_of(attribute, :within => key.options[:in])
|
129
|
-
end
|
130
|
-
if key.options[:within]
|
131
|
-
validates_inclusion_of(attribute, :within => key.options[:within])
|
132
|
-
end
|
133
|
-
|
134
|
-
if key.options[:not_in]
|
135
|
-
validates_exclusion_of(attribute, :within => key.options[:not_in])
|
136
|
-
end
|
137
|
-
|
138
|
-
if key.options[:length]
|
139
|
-
length_options = case key.options[:length]
|
140
|
-
when Integer
|
141
|
-
{:minimum => 0, :maximum => key.options[:length]}
|
142
|
-
when Range
|
143
|
-
{:within => key.options[:length]}
|
144
|
-
when Hash
|
145
|
-
key.options[:length]
|
146
|
-
end
|
147
|
-
validates_length_of(attribute, length_options)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
module InstanceMethods
|
153
|
-
def new?
|
154
|
-
@new
|
155
|
-
end
|
156
|
-
|
157
|
-
def attributes=(attrs)
|
158
|
-
return if attrs.blank?
|
159
|
-
|
160
|
-
attrs.each_pair do |name, value|
|
161
|
-
writer_method = "#{name}="
|
162
|
-
|
163
|
-
if respond_to?(writer_method)
|
164
|
-
self.send(writer_method, value)
|
165
|
-
else
|
166
|
-
self[name.to_s] = value
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
def attributes
|
172
|
-
attrs = HashWithIndifferentAccess.new
|
173
|
-
|
174
|
-
keys.each_pair do |name, key|
|
175
|
-
value = key.set(self[key.name])
|
176
|
-
attrs[name] = value
|
177
|
-
end
|
178
|
-
|
179
|
-
embedded_associations.each do |association|
|
180
|
-
if documents = instance_variable_get(association.ivar)
|
181
|
-
attrs[association.name] = documents.map { |document| document.to_mongo }
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
attrs
|
186
|
-
end
|
187
|
-
alias :to_mongo :attributes
|
188
|
-
|
189
|
-
def assign(attrs={})
|
190
|
-
self.attributes = attrs
|
191
|
-
end
|
192
|
-
|
193
|
-
def update_attributes(attrs={})
|
194
|
-
assign(attrs)
|
195
|
-
save
|
196
|
-
end
|
197
|
-
|
198
|
-
def update_attributes!(attrs={})
|
199
|
-
assign(attrs)
|
200
|
-
save!
|
201
|
-
end
|
202
|
-
|
203
|
-
def id
|
204
|
-
_id
|
205
|
-
end
|
206
|
-
|
207
|
-
def id=(value)
|
208
|
-
if self.class.using_object_id?
|
209
|
-
value = MongoMapper.normalize_object_id(value)
|
210
|
-
end
|
211
|
-
|
212
|
-
self[:_id] = value
|
213
|
-
end
|
214
|
-
|
215
|
-
def [](name)
|
216
|
-
read_key(name)
|
217
|
-
end
|
218
|
-
|
219
|
-
def []=(name, value)
|
220
|
-
ensure_key_exists(name)
|
221
|
-
write_key(name, value)
|
222
|
-
end
|
223
|
-
|
224
|
-
# @api public
|
225
|
-
def keys
|
226
|
-
self.class.keys
|
227
|
-
end
|
228
|
-
|
229
|
-
# @api private?
|
230
|
-
def key_names
|
231
|
-
keys.keys
|
232
|
-
end
|
233
|
-
|
234
|
-
# @api private?
|
235
|
-
def non_embedded_keys
|
236
|
-
keys.values.select { |key| !key.embeddable? }
|
237
|
-
end
|
238
|
-
|
239
|
-
# @api private?
|
240
|
-
def embedded_keys
|
241
|
-
keys.values.select { |key| key.embeddable? }
|
242
|
-
end
|
243
|
-
|
244
|
-
private
|
245
|
-
def assign_type_if_present
|
246
|
-
self._type = self.class.name if respond_to?(:_type=)
|
247
|
-
end
|
248
|
-
|
249
|
-
def ensure_key_exists(name)
|
250
|
-
self.class.key(name) unless respond_to?("#{name}=")
|
251
|
-
end
|
252
|
-
|
253
|
-
def read_key(name)
|
254
|
-
if key = keys[name]
|
255
|
-
var_name = "@#{name}"
|
256
|
-
value = key.get(instance_variable_get(var_name))
|
257
|
-
instance_variable_set(var_name, value)
|
258
|
-
else
|
259
|
-
raise KeyNotFound, "Could not find key: #{name.inspect}"
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
def read_key_before_typecast(name)
|
264
|
-
instance_variable_get("@#{name}_before_typecast")
|
265
|
-
end
|
266
|
-
|
267
|
-
def write_key(name, value)
|
268
|
-
key = keys[name]
|
269
|
-
instance_variable_set "@#{name}_before_typecast", value
|
270
|
-
instance_variable_set "@#{name}", key.set(value)
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
class Key
|
275
|
-
attr_accessor :name, :type, :options, :default_value
|
276
|
-
|
277
|
-
def initialize(*args)
|
278
|
-
options = args.extract_options!
|
279
|
-
@name, @type = args.shift.to_s, args.shift
|
280
|
-
self.options = (options || {}).symbolize_keys
|
281
|
-
self.default_value = self.options.delete(:default)
|
282
|
-
end
|
283
|
-
|
284
|
-
def ==(other)
|
285
|
-
@name == other.name && @type == other.type
|
286
|
-
end
|
287
|
-
|
288
|
-
def embeddable?
|
289
|
-
type.respond_to?(:embeddable?) && type.embeddable? ? true : false
|
290
|
-
end
|
291
|
-
|
292
|
-
def number?
|
293
|
-
[Integer, Float].include?(type)
|
294
|
-
end
|
295
|
-
|
296
|
-
def get(value)
|
297
|
-
if value.nil? && !default_value.nil?
|
298
|
-
return default_value
|
299
|
-
end
|
300
|
-
|
301
|
-
type.from_mongo(value)
|
302
|
-
end
|
303
|
-
|
304
|
-
def set(value)
|
305
|
-
type.to_mongo(value)
|
306
|
-
end
|
307
|
-
end
|
308
|
-
end
|
309
|
-
end
|
310
|
-
end
|