mongo_mapper 0.6.10 → 0.7.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.
- data/README.rdoc +5 -14
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/mongo_mapper.rb +48 -56
- data/lib/mongo_mapper/document.rb +136 -164
- data/lib/mongo_mapper/embedded_document.rb +29 -354
- data/lib/mongo_mapper/plugins.rb +31 -0
- data/lib/mongo_mapper/plugins/associations.rb +105 -0
- data/lib/mongo_mapper/plugins/associations/base.rb +123 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +30 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +25 -0
- data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +50 -0
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
- data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
- data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
- data/lib/mongo_mapper/plugins/associations/one_proxy.rb +68 -0
- data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
- data/lib/mongo_mapper/plugins/callbacks.rb +65 -0
- data/lib/mongo_mapper/plugins/clone.rb +13 -0
- data/lib/mongo_mapper/plugins/descendants.rb +16 -0
- data/lib/mongo_mapper/plugins/dirty.rb +119 -0
- data/lib/mongo_mapper/plugins/equality.rb +23 -0
- data/lib/mongo_mapper/plugins/identity_map.rb +122 -0
- data/lib/mongo_mapper/plugins/inspect.rb +14 -0
- data/lib/mongo_mapper/plugins/keys.rb +324 -0
- data/lib/mongo_mapper/plugins/logger.rb +17 -0
- data/lib/mongo_mapper/plugins/pagination.rb +24 -0
- data/lib/mongo_mapper/plugins/pagination/proxy.rb +68 -0
- data/lib/mongo_mapper/plugins/protected.rb +45 -0
- data/lib/mongo_mapper/plugins/rails.rb +45 -0
- data/lib/mongo_mapper/plugins/serialization.rb +105 -0
- data/lib/mongo_mapper/plugins/validations.rb +46 -0
- data/lib/mongo_mapper/query.rb +130 -0
- data/lib/mongo_mapper/support.rb +40 -17
- data/lib/mongo_mapper/support/descendant_appends.rb +46 -0
- data/lib/mongo_mapper/support/find.rb +77 -0
- data/mongo_mapper.gemspec +55 -38
- data/performance/read_write.rb +52 -0
- data/specs.watchr +23 -2
- data/test/functional/associations/test_belongs_to_proxy.rb +12 -10
- data/test/functional/associations/test_many_documents_as_proxy.rb +4 -21
- data/test/functional/associations/test_many_documents_proxy.rb +2 -8
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +59 -39
- data/test/functional/associations/test_many_embedded_proxy.rb +145 -81
- data/test/functional/associations/test_many_polymorphic_proxy.rb +2 -40
- data/test/functional/associations/test_one_proxy.rb +25 -10
- data/test/functional/test_binary.rb +2 -8
- data/test/functional/test_callbacks.rb +1 -5
- data/test/functional/test_dirty.rb +27 -23
- data/test/functional/test_document.rb +224 -165
- data/test/functional/test_embedded_document.rb +72 -82
- data/test/functional/test_identity_map.rb +508 -0
- data/test/functional/test_modifiers.rb +15 -5
- data/test/functional/test_pagination.rb +1 -3
- data/test/functional/test_protected.rb +155 -0
- data/test/functional/test_string_id_compatibility.rb +7 -12
- data/test/functional/test_validations.rb +26 -58
- data/test/models.rb +0 -39
- data/test/test_helper.rb +37 -3
- data/test/unit/associations/test_base.rb +5 -5
- data/test/unit/associations/test_proxy.rb +8 -6
- data/test/unit/test_descendant_appends.rb +71 -0
- data/test/unit/test_document.rb +71 -76
- data/test/unit/test_dynamic_finder.rb +27 -29
- data/test/unit/test_embedded_document.rb +555 -601
- data/test/unit/{test_key.rb → test_keys.rb} +2 -5
- data/test/unit/test_mongo_mapper.rb +69 -9
- data/test/unit/test_pagination.rb +40 -32
- data/test/unit/test_plugins.rb +50 -0
- data/test/unit/{test_finder_options.rb → test_query.rb} +74 -65
- data/test/unit/test_rails.rb +123 -0
- data/test/unit/{test_serializations.rb → test_serialization.rb} +1 -2
- data/test/unit/test_support.rb +23 -7
- data/test/unit/test_time_zones.rb +3 -4
- data/test/unit/test_validations.rb +58 -17
- metadata +53 -36
- data/lib/mongo_mapper/associations.rb +0 -78
- data/lib/mongo_mapper/associations/base.rb +0 -119
- data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +0 -26
- data/lib/mongo_mapper/associations/belongs_to_proxy.rb +0 -21
- data/lib/mongo_mapper/associations/collection.rb +0 -19
- data/lib/mongo_mapper/associations/in_array_proxy.rb +0 -137
- data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +0 -26
- data/lib/mongo_mapper/associations/many_documents_proxy.rb +0 -115
- data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +0 -31
- data/lib/mongo_mapper/associations/many_embedded_proxy.rb +0 -54
- data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +0 -11
- data/lib/mongo_mapper/associations/one_proxy.rb +0 -64
- data/lib/mongo_mapper/associations/proxy.rb +0 -116
- data/lib/mongo_mapper/callbacks.rb +0 -61
- data/lib/mongo_mapper/dirty.rb +0 -117
- data/lib/mongo_mapper/dynamic_finder.rb +0 -74
- data/lib/mongo_mapper/finder_options.rb +0 -145
- data/lib/mongo_mapper/key.rb +0 -36
- data/lib/mongo_mapper/mongo_mapper.rb +0 -125
- data/lib/mongo_mapper/pagination.rb +0 -66
- data/lib/mongo_mapper/rails_compatibility/document.rb +0 -15
- data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +0 -28
- data/lib/mongo_mapper/serialization.rb +0 -54
- data/lib/mongo_mapper/serializers/json_serializer.rb +0 -48
- data/lib/mongo_mapper/validations.rb +0 -39
- data/test/functional/test_rails_compatibility.rb +0 -25
@@ -1,78 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Associations
|
3
|
-
module ClassMethods
|
4
|
-
def belongs_to(association_id, options={}, &extension)
|
5
|
-
create_association(:belongs_to, association_id, options, &extension)
|
6
|
-
end
|
7
|
-
|
8
|
-
def many(association_id, options={}, &extension)
|
9
|
-
create_association(:many, association_id, options, &extension)
|
10
|
-
end
|
11
|
-
|
12
|
-
def one(association_id, options={}, &extension)
|
13
|
-
create_association(:one, association_id, options, &extension)
|
14
|
-
end
|
15
|
-
|
16
|
-
def associations
|
17
|
-
@associations ||= HashWithIndifferentAccess.new
|
18
|
-
end
|
19
|
-
|
20
|
-
def associations=(hash)
|
21
|
-
@associations = hash
|
22
|
-
end
|
23
|
-
|
24
|
-
def inherited(subclass)
|
25
|
-
subclass.associations = associations.dup
|
26
|
-
super
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
def create_association(type, name, options, &extension)
|
31
|
-
association = Associations::Base.new(type, name, options, &extension)
|
32
|
-
associations[association.name] = association
|
33
|
-
|
34
|
-
define_method(association.name) do
|
35
|
-
get_proxy(association)
|
36
|
-
end
|
37
|
-
|
38
|
-
define_method("#{association.name}=") do |value|
|
39
|
-
get_proxy(association).replace(value)
|
40
|
-
value
|
41
|
-
end
|
42
|
-
|
43
|
-
if association.one? || association.belongs_to?
|
44
|
-
define_method("#{association.name}?") do
|
45
|
-
get_proxy(association).present?
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
if association.options[:dependent] && association.many? && !association.embeddable?
|
50
|
-
after_destroy do |doc|
|
51
|
-
case association.options[:dependent]
|
52
|
-
when :destroy
|
53
|
-
doc.get_proxy(association).destroy_all
|
54
|
-
when :delete_all
|
55
|
-
doc.get_proxy(association).delete_all
|
56
|
-
when :nullify
|
57
|
-
doc.get_proxy(association).nullify
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
module InstanceMethods
|
65
|
-
def associations
|
66
|
-
self.class.associations
|
67
|
-
end
|
68
|
-
|
69
|
-
def get_proxy(association)
|
70
|
-
unless proxy = self.instance_variable_get(association.ivar)
|
71
|
-
proxy = association.proxy_class.new(self, association)
|
72
|
-
self.instance_variable_set(association.ivar, proxy)
|
73
|
-
end
|
74
|
-
proxy
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
@@ -1,119 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Associations
|
3
|
-
class Base
|
4
|
-
attr_reader :type, :name, :options, :finder_options
|
5
|
-
|
6
|
-
# Options that should not be considered MongoDB query options/criteria
|
7
|
-
AssociationOptions = [:as, :class, :class_name, :dependent, :extend, :foreign_key, :in, :polymorphic]
|
8
|
-
|
9
|
-
def initialize(type, name, options={}, &extension)
|
10
|
-
@type, @name, @options, @finder_options = type, name, {}, {}
|
11
|
-
options.symbolize_keys!
|
12
|
-
|
13
|
-
options[:extend] = modulized_extensions(extension, options[:extend])
|
14
|
-
|
15
|
-
options.each_pair do |key, value|
|
16
|
-
if AssociationOptions.include?(key)
|
17
|
-
@options[key] = value
|
18
|
-
else
|
19
|
-
@finder_options[key] = value
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def class_name
|
25
|
-
@class_name ||= begin
|
26
|
-
if cn = options[:class_name]
|
27
|
-
cn
|
28
|
-
elsif many?
|
29
|
-
name.to_s.singularize.camelize
|
30
|
-
else
|
31
|
-
name.to_s.camelize
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def klass
|
37
|
-
@klass ||= options[:class] || class_name.constantize
|
38
|
-
end
|
39
|
-
|
40
|
-
def many?
|
41
|
-
@many_type ||= @type == :many
|
42
|
-
end
|
43
|
-
|
44
|
-
def belongs_to?
|
45
|
-
@belongs_to_type ||= @type == :belongs_to
|
46
|
-
end
|
47
|
-
|
48
|
-
def one?
|
49
|
-
@one_type ||= @type == :one
|
50
|
-
end
|
51
|
-
|
52
|
-
def polymorphic?
|
53
|
-
!!@options[:polymorphic]
|
54
|
-
end
|
55
|
-
|
56
|
-
def as?
|
57
|
-
!!@options[:as]
|
58
|
-
end
|
59
|
-
|
60
|
-
def in_array?
|
61
|
-
!!@options[:in]
|
62
|
-
end
|
63
|
-
|
64
|
-
def embeddable?
|
65
|
-
many? && klass.embeddable?
|
66
|
-
end
|
67
|
-
|
68
|
-
def type_key_name
|
69
|
-
@type_key_name ||= many? ? '_type' : "#{as}_type"
|
70
|
-
end
|
71
|
-
|
72
|
-
def as
|
73
|
-
@options[:as] || self.name
|
74
|
-
end
|
75
|
-
|
76
|
-
def foreign_key
|
77
|
-
@options[:foreign_key] || "#{name}_id"
|
78
|
-
end
|
79
|
-
|
80
|
-
def ivar
|
81
|
-
@ivar ||= "@_#{name}"
|
82
|
-
end
|
83
|
-
|
84
|
-
def proxy_class
|
85
|
-
@proxy_class ||= begin
|
86
|
-
if many?
|
87
|
-
if self.klass.embeddable?
|
88
|
-
polymorphic? ? ManyEmbeddedPolymorphicProxy : ManyEmbeddedProxy
|
89
|
-
else
|
90
|
-
if polymorphic?
|
91
|
-
ManyPolymorphicProxy
|
92
|
-
elsif as?
|
93
|
-
ManyDocumentsAsProxy
|
94
|
-
elsif in_array?
|
95
|
-
InArrayProxy
|
96
|
-
else
|
97
|
-
ManyDocumentsProxy
|
98
|
-
end
|
99
|
-
end
|
100
|
-
elsif one?
|
101
|
-
OneProxy
|
102
|
-
else
|
103
|
-
polymorphic? ? BelongsToPolymorphicProxy : BelongsToProxy
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
private
|
109
|
-
|
110
|
-
# @param [Array<Module, Proc>] extensions a collection of Modules or
|
111
|
-
# Procs that extend the behaviour of this association.
|
112
|
-
def modulized_extensions(*extensions)
|
113
|
-
extensions.flatten.compact.map do |extension|
|
114
|
-
Proc === extension ? Module.new(&extension) : extension
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Associations
|
3
|
-
class BelongsToPolymorphicProxy < Proxy
|
4
|
-
def replace(doc)
|
5
|
-
if doc
|
6
|
-
doc.save if doc.new?
|
7
|
-
id, type = doc.id, doc.class.name
|
8
|
-
end
|
9
|
-
|
10
|
-
owner[reflection.foreign_key] = id
|
11
|
-
owner[reflection.type_key_name] = type
|
12
|
-
reset
|
13
|
-
end
|
14
|
-
|
15
|
-
protected
|
16
|
-
def find_target
|
17
|
-
return nil if association_class.nil? || owner[reflection.foreign_key].nil?
|
18
|
-
association_class.first(:id => owner[reflection.foreign_key])
|
19
|
-
end
|
20
|
-
|
21
|
-
def association_class
|
22
|
-
proxy_owner[reflection.type_key_name] ? proxy_owner[reflection.type_key_name].constantize : nil
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Associations
|
3
|
-
class BelongsToProxy < Proxy
|
4
|
-
def replace(doc)
|
5
|
-
if doc
|
6
|
-
doc.save if doc.new?
|
7
|
-
id = doc.id
|
8
|
-
end
|
9
|
-
|
10
|
-
owner[reflection.foreign_key] = id
|
11
|
-
reset
|
12
|
-
end
|
13
|
-
|
14
|
-
protected
|
15
|
-
def find_target
|
16
|
-
return nil if owner[reflection.foreign_key].nil?
|
17
|
-
klass.first(:id => owner[reflection.foreign_key])
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,137 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Associations
|
3
|
-
class InArrayProxy < Collection
|
4
|
-
include ::MongoMapper::Finders
|
5
|
-
|
6
|
-
def find(*args)
|
7
|
-
options = args.extract_options!
|
8
|
-
|
9
|
-
case args.first
|
10
|
-
when :first
|
11
|
-
first(options)
|
12
|
-
when :last
|
13
|
-
last(options)
|
14
|
-
when :all
|
15
|
-
all(options)
|
16
|
-
else
|
17
|
-
klass.find(*scoped_ids(args) << scoped_options(options))
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def find!(*args)
|
22
|
-
options = args.extract_options!
|
23
|
-
|
24
|
-
case args.first
|
25
|
-
when :first
|
26
|
-
first(options)
|
27
|
-
when :last
|
28
|
-
last(options)
|
29
|
-
when :all
|
30
|
-
all(options)
|
31
|
-
else
|
32
|
-
klass.find!(*scoped_ids(args) << scoped_options(options))
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def paginate(options)
|
37
|
-
klass.paginate(scoped_options(options))
|
38
|
-
end
|
39
|
-
|
40
|
-
def all(options={})
|
41
|
-
klass.all(scoped_options(options))
|
42
|
-
end
|
43
|
-
|
44
|
-
def first(options={})
|
45
|
-
klass.first(scoped_options(options))
|
46
|
-
end
|
47
|
-
|
48
|
-
def last(options={})
|
49
|
-
klass.last(scoped_options(options))
|
50
|
-
end
|
51
|
-
|
52
|
-
def count(options={})
|
53
|
-
options.blank? ? ids.size : klass.count(scoped_options(options))
|
54
|
-
end
|
55
|
-
|
56
|
-
def destroy_all(options={})
|
57
|
-
all(options).each do |doc|
|
58
|
-
ids.delete(doc.id)
|
59
|
-
doc.destroy
|
60
|
-
end
|
61
|
-
reset
|
62
|
-
end
|
63
|
-
|
64
|
-
def delete_all(options={})
|
65
|
-
docs = all(options.merge(:select => ['_id']))
|
66
|
-
docs.each { |doc| ids.delete(doc.id) }
|
67
|
-
klass.delete(docs.map(&:id))
|
68
|
-
reset
|
69
|
-
end
|
70
|
-
|
71
|
-
def nullify
|
72
|
-
replace([])
|
73
|
-
reset
|
74
|
-
end
|
75
|
-
|
76
|
-
def create(attrs={})
|
77
|
-
doc = klass.create(attrs)
|
78
|
-
unless doc.new?
|
79
|
-
ids << doc.id
|
80
|
-
owner.save
|
81
|
-
end
|
82
|
-
doc
|
83
|
-
end
|
84
|
-
|
85
|
-
def create!(attrs={})
|
86
|
-
doc = klass.create!(attrs)
|
87
|
-
unless doc.new?
|
88
|
-
ids << doc.id
|
89
|
-
owner.save
|
90
|
-
end
|
91
|
-
doc
|
92
|
-
end
|
93
|
-
|
94
|
-
def <<(*docs)
|
95
|
-
flatten_deeper(docs).each do |doc|
|
96
|
-
doc.save if doc.new?
|
97
|
-
unless ids.include?(doc.id)
|
98
|
-
ids << doc.id
|
99
|
-
end
|
100
|
-
end
|
101
|
-
reset
|
102
|
-
end
|
103
|
-
alias_method :push, :<<
|
104
|
-
alias_method :concat, :<<
|
105
|
-
|
106
|
-
def replace(docs)
|
107
|
-
doc_ids = docs.map do |doc|
|
108
|
-
doc.save if doc.new?
|
109
|
-
doc.id
|
110
|
-
end
|
111
|
-
ids.replace(doc_ids.uniq)
|
112
|
-
reset
|
113
|
-
end
|
114
|
-
|
115
|
-
private
|
116
|
-
def scoped_conditions
|
117
|
-
{:_id => ids}
|
118
|
-
end
|
119
|
-
|
120
|
-
def scoped_options(options)
|
121
|
-
reflection.finder_options.merge(options).merge(scoped_conditions)
|
122
|
-
end
|
123
|
-
|
124
|
-
def scoped_ids(args)
|
125
|
-
args.flatten.reject { |id| !ids.include?(id) }
|
126
|
-
end
|
127
|
-
|
128
|
-
def find_target
|
129
|
-
ids.blank? ? [] : all
|
130
|
-
end
|
131
|
-
|
132
|
-
def ids
|
133
|
-
owner[options[:in]]
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Associations
|
3
|
-
class ManyDocumentsAsProxy < ManyDocumentsProxy
|
4
|
-
protected
|
5
|
-
def scoped_conditions
|
6
|
-
{type_key_name => owner.class.name, id_key_name => owner.id}
|
7
|
-
end
|
8
|
-
|
9
|
-
def apply_scope(doc)
|
10
|
-
ensure_owner_saved
|
11
|
-
doc[type_key_name] = owner.class.name
|
12
|
-
doc[id_key_name] = owner.id
|
13
|
-
doc
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
def type_key_name
|
18
|
-
"#{options[:as]}_type"
|
19
|
-
end
|
20
|
-
|
21
|
-
def id_key_name
|
22
|
-
"#{options[:as]}_id"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,115 +0,0 @@
|
|
1
|
-
module MongoMapper
|
2
|
-
module Associations
|
3
|
-
class ManyDocumentsProxy < Collection
|
4
|
-
include ::MongoMapper::Finders
|
5
|
-
|
6
|
-
def find(*args)
|
7
|
-
options = args.extract_options!
|
8
|
-
klass.find(*args << scoped_options(options))
|
9
|
-
end
|
10
|
-
|
11
|
-
def find!(*args)
|
12
|
-
options = args.extract_options!
|
13
|
-
klass.find!(*args << scoped_options(options))
|
14
|
-
end
|
15
|
-
|
16
|
-
def paginate(options)
|
17
|
-
klass.paginate(scoped_options(options))
|
18
|
-
end
|
19
|
-
|
20
|
-
def all(options={})
|
21
|
-
klass.all(scoped_options(options))
|
22
|
-
end
|
23
|
-
|
24
|
-
def first(options={})
|
25
|
-
klass.first(scoped_options(options))
|
26
|
-
end
|
27
|
-
|
28
|
-
def last(options={})
|
29
|
-
klass.last(scoped_options(options))
|
30
|
-
end
|
31
|
-
|
32
|
-
def count(options={})
|
33
|
-
klass.count(scoped_options(options))
|
34
|
-
end
|
35
|
-
|
36
|
-
def replace(docs)
|
37
|
-
load_target
|
38
|
-
target.map(&:destroy)
|
39
|
-
docs.each { |doc| apply_scope(doc).save }
|
40
|
-
reset
|
41
|
-
end
|
42
|
-
|
43
|
-
def <<(*docs)
|
44
|
-
ensure_owner_saved
|
45
|
-
flatten_deeper(docs).each { |doc| apply_scope(doc).save }
|
46
|
-
reset
|
47
|
-
end
|
48
|
-
alias_method :push, :<<
|
49
|
-
alias_method :concat, :<<
|
50
|
-
|
51
|
-
def build(attrs={})
|
52
|
-
doc = klass.new(attrs)
|
53
|
-
apply_scope(doc)
|
54
|
-
doc
|
55
|
-
end
|
56
|
-
|
57
|
-
def create(attrs={})
|
58
|
-
doc = klass.new(attrs)
|
59
|
-
apply_scope(doc).save
|
60
|
-
doc
|
61
|
-
end
|
62
|
-
|
63
|
-
def create!(attrs={})
|
64
|
-
doc = klass.new(attrs)
|
65
|
-
apply_scope(doc).save!
|
66
|
-
doc
|
67
|
-
end
|
68
|
-
|
69
|
-
def destroy_all(options={})
|
70
|
-
all(options).map(&:destroy)
|
71
|
-
reset
|
72
|
-
end
|
73
|
-
|
74
|
-
def delete_all(options={})
|
75
|
-
klass.delete_all(options.merge(scoped_conditions))
|
76
|
-
reset
|
77
|
-
end
|
78
|
-
|
79
|
-
def nullify
|
80
|
-
criteria = FinderOptions.new(klass, scoped_conditions).criteria
|
81
|
-
all(criteria).each do |doc|
|
82
|
-
doc.update_attributes(self.foreign_key => nil)
|
83
|
-
end
|
84
|
-
reset
|
85
|
-
end
|
86
|
-
|
87
|
-
protected
|
88
|
-
def scoped_conditions
|
89
|
-
{self.foreign_key => owner.id}
|
90
|
-
end
|
91
|
-
|
92
|
-
def scoped_options(options)
|
93
|
-
reflection.finder_options.merge(options).merge(scoped_conditions)
|
94
|
-
end
|
95
|
-
|
96
|
-
def find_target
|
97
|
-
all
|
98
|
-
end
|
99
|
-
|
100
|
-
def ensure_owner_saved
|
101
|
-
owner.save if owner.new?
|
102
|
-
end
|
103
|
-
|
104
|
-
def apply_scope(doc)
|
105
|
-
ensure_owner_saved
|
106
|
-
doc[foreign_key] = owner.id
|
107
|
-
doc
|
108
|
-
end
|
109
|
-
|
110
|
-
def foreign_key
|
111
|
-
options[:foreign_key] || owner.class.name.underscore.gsub("/", "_") + "_id"
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|