datastax_rails 2.0.12 → 2.0.15
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.
- checksums.yaml +4 -4
- data/Rakefile +5 -5
- data/lib/blankslate.rb +8 -11
- data/lib/cql-rb_extensions.rb +5 -3
- data/lib/datastax_rails/associations/association.rb +93 -101
- data/lib/datastax_rails/associations/association_scope.rb +7 -7
- data/lib/datastax_rails/associations/belongs_to_association.rb +46 -48
- data/lib/datastax_rails/associations/builder/association.rb +32 -31
- data/lib/datastax_rails/associations/builder/belongs_to.rb +19 -20
- data/lib/datastax_rails/associations/builder/collection_association.rb +32 -32
- data/lib/datastax_rails/associations/builder/has_and_belongs_to_many.rb +21 -21
- data/lib/datastax_rails/associations/builder/has_many.rb +39 -40
- data/lib/datastax_rails/associations/builder/has_one.rb +30 -31
- data/lib/datastax_rails/associations/builder/singular_association.rb +31 -33
- data/lib/datastax_rails/associations/collection_association.rb +129 -135
- data/lib/datastax_rails/associations/collection_proxy.rb +21 -21
- data/lib/datastax_rails/associations/has_and_belongs_to_many_association.rb +26 -26
- data/lib/datastax_rails/associations/has_many_association.rb +38 -38
- data/lib/datastax_rails/associations/has_one_association.rb +31 -32
- data/lib/datastax_rails/associations/singular_association.rb +31 -30
- data/lib/datastax_rails/associations.rb +27 -24
- data/lib/datastax_rails/attribute_assignment.rb +17 -17
- data/lib/datastax_rails/attribute_methods/definition.rb +4 -4
- data/lib/datastax_rails/attribute_methods/dirty.rb +34 -33
- data/lib/datastax_rails/attribute_methods/primary_key.rb +3 -8
- data/lib/datastax_rails/attribute_methods/read.rb +10 -12
- data/lib/datastax_rails/attribute_methods/typecasting.rb +36 -35
- data/lib/datastax_rails/attribute_methods/write.rb +5 -6
- data/lib/datastax_rails/attribute_methods.rb +52 -56
- data/lib/datastax_rails/base.rb +122 -125
- data/lib/datastax_rails/callbacks.rb +15 -9
- data/lib/datastax_rails/cassandra_only_model.rb +6 -6
- data/lib/datastax_rails/collection.rb +5 -7
- data/lib/datastax_rails/column.rb +130 -118
- data/lib/datastax_rails/connection/statement_cache.rb +3 -3
- data/lib/datastax_rails/connection.rb +42 -33
- data/lib/datastax_rails/cql/alter_column_family.rb +19 -21
- data/lib/datastax_rails/cql/base.rb +8 -11
- data/lib/datastax_rails/cql/column_family.rb +11 -10
- data/lib/datastax_rails/cql/consistency.rb +2 -2
- data/lib/datastax_rails/cql/create_column_family.rb +15 -15
- data/lib/datastax_rails/cql/create_index.rb +5 -5
- data/lib/datastax_rails/cql/create_keyspace.rb +7 -7
- data/lib/datastax_rails/cql/delete.rb +16 -29
- data/lib/datastax_rails/cql/drop_column_family.rb +2 -2
- data/lib/datastax_rails/cql/drop_index.rb +2 -2
- data/lib/datastax_rails/cql/drop_keyspace.rb +2 -2
- data/lib/datastax_rails/cql/insert.rb +10 -16
- data/lib/datastax_rails/cql/select.rb +21 -33
- data/lib/datastax_rails/cql/truncate.rb +2 -2
- data/lib/datastax_rails/cql/update.rb +16 -24
- data/lib/datastax_rails/cql/use_keyspace.rb +2 -2
- data/lib/datastax_rails/cql.rb +2 -2
- data/lib/datastax_rails/dynamic_model.rb +32 -29
- data/lib/datastax_rails/errors.rb +6 -6
- data/lib/datastax_rails/grouped_collection.rb +3 -3
- data/lib/datastax_rails/inheritance.rb +9 -9
- data/lib/datastax_rails/payload_model.rb +24 -20
- data/lib/datastax_rails/persistence.rb +116 -110
- data/lib/datastax_rails/railtie.rb +7 -7
- data/lib/datastax_rails/reflection.rb +61 -59
- data/lib/datastax_rails/relation/batches.rb +12 -13
- data/lib/datastax_rails/relation/facet_methods.rb +44 -33
- data/lib/datastax_rails/relation/finder_methods.rb +95 -91
- data/lib/datastax_rails/relation/modification_methods.rb +5 -5
- data/lib/datastax_rails/relation/search_methods.rb +102 -102
- data/lib/datastax_rails/relation/spawn_methods.rb +25 -24
- data/lib/datastax_rails/relation/stats_methods.rb +9 -8
- data/lib/datastax_rails/relation.rb +165 -170
- data/lib/datastax_rails/rsolr_client_wrapper.rb +3 -3
- data/lib/datastax_rails/schema/cassandra.rb +44 -43
- data/lib/datastax_rails/schema/migrator.rb +52 -52
- data/lib/datastax_rails/schema/solr.rb +55 -47
- data/lib/datastax_rails/schema_cache.rb +1 -3
- data/lib/datastax_rails/scoping/default.rb +2 -3
- data/lib/datastax_rails/scoping/named.rb +3 -5
- data/lib/datastax_rails/scoping.rb +11 -12
- data/lib/datastax_rails/serialization.rb +34 -31
- data/lib/datastax_rails/serializers/xml_serializer.rb +178 -175
- data/lib/datastax_rails/timestamps.rb +4 -4
- data/lib/datastax_rails/types/dirty_collection.rb +57 -57
- data/lib/datastax_rails/types/dynamic_list.rb +1 -1
- data/lib/datastax_rails/types/dynamic_map.rb +5 -7
- data/lib/datastax_rails/types/dynamic_set.rb +2 -2
- data/lib/datastax_rails/util/solr_repair.rb +3 -3
- data/lib/datastax_rails/validations/associated.rb +8 -6
- data/lib/datastax_rails/validations/uniqueness.rb +8 -8
- data/lib/datastax_rails/validations.rb +9 -10
- data/lib/datastax_rails/version.rb +2 -1
- data/lib/datastax_rails/wide_storage_model.rb +6 -6
- data/lib/datastax_rails.rb +13 -9
- data/lib/schema_migration.rb +3 -3
- data/spec/datastax_rails/associations/belongs_to_association_spec.rb +2 -2
- data/spec/datastax_rails/associations/collection_association_spec.rb +14 -14
- data/spec/datastax_rails/associations/has_many_association_spec.rb +20 -20
- data/spec/datastax_rails/associations_spec.rb +11 -11
- data/spec/datastax_rails/attribute_methods_spec.rb +25 -25
- data/spec/datastax_rails/base_spec.rb +24 -24
- data/spec/datastax_rails/callbacks_spec.rb +21 -21
- data/spec/datastax_rails/column_spec.rb +133 -132
- data/spec/datastax_rails/connection/statement_cache_spec.rb +2 -2
- data/spec/datastax_rails/cql/base_spec.rb +4 -4
- data/spec/datastax_rails/cql/delete_spec.rb +19 -0
- data/spec/datastax_rails/cql/select_spec.rb +8 -8
- data/spec/datastax_rails/cql/update_spec.rb +8 -10
- data/spec/datastax_rails/dynamic_model_spec.rb +36 -22
- data/spec/datastax_rails/inheritance_spec.rb +11 -14
- data/spec/datastax_rails/persistence_spec.rb +73 -74
- data/spec/datastax_rails/relation/batches_spec.rb +13 -13
- data/spec/datastax_rails/relation/facet_methods_spec.rb +43 -35
- data/spec/datastax_rails/relation/finder_methods_spec.rb +77 -78
- data/spec/datastax_rails/relation/modification_methods_spec.rb +19 -19
- data/spec/datastax_rails/relation/search_methods_spec.rb +160 -160
- data/spec/datastax_rails/relation/spawn_methods_spec.rb +18 -18
- data/spec/datastax_rails/relation_spec.rb +119 -116
- data/spec/datastax_rails/schema/migrator_spec.rb +30 -30
- data/spec/datastax_rails/schema/solr_spec.rb +15 -15
- data/spec/datastax_rails/scoping/default_spec.rb +9 -9
- data/spec/datastax_rails/types/dynamic_list_spec.rb +12 -12
- data/spec/datastax_rails/types/dynamic_map_spec.rb +10 -10
- data/spec/datastax_rails/types/dynamic_set_spec.rb +22 -10
- data/spec/datastax_rails/validations/uniqueness_spec.rb +25 -25
- data/spec/datastax_rails/wide_storage_model_spec.rb +11 -0
- data/spec/datastax_rails_spec.rb +2 -2
- data/spec/dummy/config/application.rb +2 -3
- data/spec/dummy/config/boot.rb +1 -1
- data/spec/dummy/config/environments/development.rb +3 -3
- data/spec/dummy/config/environments/test.rb +1 -1
- data/spec/dummy/config/initializers/session_store.rb +1 -1
- data/spec/dummy/config/initializers/wrap_parameters.rb +1 -1
- data/spec/factories/audit_logs.rb +6 -0
- data/spec/factories/hobbies.rb +6 -0
- data/spec/factories/people.rb +5 -0
- data/spec/feature/dynamic_fields_spec.rb +4 -4
- data/spec/feature/overloaded_tables_spec.rb +11 -12
- data/spec/spec_helper.rb +17 -14
- data/spec/support/datastax_test_hook.rb +2 -2
- data/spec/support/default_consistency_shared_examples.rb +11 -11
- data/spec/support/models.rb +31 -32
- metadata +40 -6
- data/lib/datastax_rails/attribute_methods/before_type_cast.rb +0 -71
- data/lib/datastax_rails/log_subscriber.rb +0 -0
- data/spec/dummy/ks/migrate/20111117224534_models.rb +0 -20
@@ -1,8 +1,8 @@
|
|
1
|
-
module DatastaxRails::Associations::Builder
|
1
|
+
module DatastaxRails::Associations::Builder # rubocop:disable Style/ClassAndModuleChildren
|
2
2
|
class SingularAssociation < Association #:nodoc:
|
3
|
-
#self.valid_options += [:remote, :dependent, :counter_cache, :primary_key, :inverse_of]
|
3
|
+
# self.valid_options += [:remote, :dependent, :counter_cache, :primary_key, :inverse_of]
|
4
4
|
self.valid_options += [:dependent, :denorm]
|
5
|
-
|
5
|
+
|
6
6
|
def constructable?
|
7
7
|
true
|
8
8
|
end
|
@@ -11,7 +11,7 @@ module DatastaxRails::Associations::Builder
|
|
11
11
|
super
|
12
12
|
define_constructors if constructable?
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def build
|
16
16
|
relation = super
|
17
17
|
configure_denorm
|
@@ -19,38 +19,36 @@ module DatastaxRails::Associations::Builder
|
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
22
|
-
|
23
|
-
def configure_denorm
|
24
|
-
if options[:denorm]
|
25
|
-
unless options[:denorm].is_a?(Hash)
|
26
|
-
raise ArgumentError, "The :denorm option expects a hash in the form {:attr_on_other_model => :virtual_attr_on_this_model}"
|
27
|
-
end
|
28
|
-
|
29
|
-
# options[:denorm].each do |remote, local|
|
30
|
-
# # Default everything to a string. If it should be something different, the developer can declare the attribute manually.
|
31
|
-
# model.send(:string, local)
|
32
|
-
# model.send(:class_eval, <<-eoruby, __FILE__, __LINE__ + 1)
|
33
|
-
# def #{local}
|
34
|
-
# eoruby
|
35
|
-
# end
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
39
22
|
|
40
|
-
|
41
|
-
|
23
|
+
def configure_denorm
|
24
|
+
return unless options[:denorm]
|
25
|
+
options[:denorm].is_a?(Hash) || fail(ArgumentError, 'The :denorm option expects a hash in the form ' \
|
26
|
+
'{:attr_on_other_model => :virtual_attr_on_this_model}')
|
42
27
|
|
43
|
-
|
44
|
-
|
45
|
-
|
28
|
+
# options[:denorm].each do |remote, local|
|
29
|
+
# # Default everything to a string. If it should be something different,
|
30
|
+
# # the developer can declare the attribute manually.
|
31
|
+
# model.send(:string, local)
|
32
|
+
# model.send(:class_eval, <<-eoruby, __FILE__, __LINE__ + 1)
|
33
|
+
# def #{local}
|
34
|
+
# eoruby
|
35
|
+
# end
|
36
|
+
end
|
46
37
|
|
47
|
-
|
48
|
-
|
49
|
-
end
|
38
|
+
def define_constructors
|
39
|
+
name = self.name
|
50
40
|
|
51
|
-
|
52
|
-
|
53
|
-
end
|
41
|
+
model.redefine_method("build_#{name}") do |*params, &block|
|
42
|
+
association(name).build(*params, &block)
|
54
43
|
end
|
44
|
+
|
45
|
+
model.redefine_method("create_#{name}") do |*params, &block|
|
46
|
+
association(name).create(*params, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
model.redefine_method("create_#{name}!") do |*params, &block|
|
50
|
+
association(name).create!(*params, &block)
|
51
|
+
end
|
52
|
+
end
|
55
53
|
end
|
56
|
-
end
|
54
|
+
end
|
@@ -17,14 +17,14 @@ module DatastaxRails
|
|
17
17
|
# +load_target+ and the +loaded+ flag are your friends.
|
18
18
|
class CollectionAssociation < Association #:nodoc:
|
19
19
|
attr_reader :proxy
|
20
|
-
|
21
|
-
delegate :first, :last, :
|
22
|
-
|
20
|
+
|
21
|
+
delegate :first, :last, to: :scoped
|
22
|
+
|
23
23
|
def initialize(owner, reflection)
|
24
24
|
super
|
25
25
|
@proxy = CollectionProxy.new(self)
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def size
|
29
29
|
if !find_target? || loaded?
|
30
30
|
target.size
|
@@ -36,33 +36,30 @@ module DatastaxRails
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
alias_method :count, :size
|
39
|
-
|
39
|
+
|
40
40
|
def empty?
|
41
41
|
size == 0
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
def any?
|
45
45
|
size > 0
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def many?
|
49
49
|
size > 1
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
# Implements the reader method, e.g. foo.items for Foo.has_many :items
|
53
53
|
def reader(force_reload = false)
|
54
|
-
if force_reload || stale_target?
|
55
|
-
reload
|
56
|
-
end
|
57
|
-
|
54
|
+
reload if force_reload || stale_target?
|
58
55
|
proxy
|
59
56
|
end
|
60
|
-
|
57
|
+
|
61
58
|
# Implements the writer method, e.g. foo.items= for Foo.has_many :items
|
62
59
|
def writer(records)
|
63
60
|
replace(records)
|
64
61
|
end
|
65
|
-
|
62
|
+
|
66
63
|
# Implements the ids reader method, e.g. foo.item_ids for Foo.has_many :items
|
67
64
|
def ids_reader
|
68
65
|
if loaded?
|
@@ -75,21 +72,21 @@ module DatastaxRails
|
|
75
72
|
end
|
76
73
|
end
|
77
74
|
end
|
78
|
-
|
75
|
+
|
79
76
|
# Implements the ids writer method, e.g. foo.item_ids= for Foo.has_many :items
|
80
77
|
def ids_writer(ids)
|
81
78
|
ids = Array.wrap(ids).reject { |id| id.blank? }
|
82
79
|
replace(klass.find(ids).index_by { |r| r.id }.values_at(*ids))
|
83
80
|
end
|
84
|
-
|
81
|
+
|
85
82
|
def reset
|
86
83
|
@loaded = false
|
87
84
|
@target = []
|
88
85
|
end
|
89
|
-
|
86
|
+
|
90
87
|
def build(attributes = {}, options = {}, &block)
|
91
88
|
if attributes.is_a?(Array)
|
92
|
-
attributes.
|
89
|
+
attributes.map { |attr| build(attr, options, &block) }
|
93
90
|
else
|
94
91
|
add_to_target(build_record(attributes, options)) do |record|
|
95
92
|
yield(record) if block_given?
|
@@ -104,7 +101,7 @@ module DatastaxRails
|
|
104
101
|
def create!(attributes = {}, options = {}, &block)
|
105
102
|
create_record(attributes, options, true, &block)
|
106
103
|
end
|
107
|
-
|
104
|
+
|
108
105
|
# Remove all records from this association
|
109
106
|
#
|
110
107
|
# See delete for more info.
|
@@ -124,7 +121,7 @@ module DatastaxRails
|
|
124
121
|
loaded!
|
125
122
|
end
|
126
123
|
end
|
127
|
-
|
124
|
+
|
128
125
|
# Removes +records+ from this association calling +before_remove+ and
|
129
126
|
# +after_remove+ callbacks.
|
130
127
|
#
|
@@ -142,31 +139,28 @@ module DatastaxRails
|
|
142
139
|
# Note that this method will _always_ remove records from the database
|
143
140
|
# ignoring the +:dependent+ option.
|
144
141
|
def destroy(*records)
|
145
|
-
records = find(records) if records.any? { |record| record.
|
142
|
+
records = find(records) if records.any? { |record| record.is_a?(Fixnum) || record.is_a?(String) }
|
146
143
|
delete_or_destroy(records, :destroy)
|
147
144
|
end
|
148
|
-
|
145
|
+
|
149
146
|
def uniq(collection = load_target)
|
150
147
|
seen = {}
|
151
|
-
collection.
|
148
|
+
collection.select do |record|
|
152
149
|
seen[record.id] = true unless seen.key?(record.id)
|
153
150
|
end
|
154
151
|
end
|
155
|
-
|
156
|
-
def load_target
|
157
|
-
if find_target?
|
158
|
-
@target = merge_target_lists(find_target, target)
|
159
|
-
end
|
160
152
|
|
153
|
+
def load_target
|
154
|
+
@target = merge_target_lists(find_target, target) if find_target?
|
161
155
|
loaded!
|
162
156
|
target
|
163
157
|
end
|
164
|
-
|
158
|
+
|
165
159
|
def add_to_target(record)
|
166
160
|
callback(:before_add, record)
|
167
161
|
yield(record) if block_given?
|
168
162
|
|
169
|
-
if options[:uniq] && index = @target.index(record)
|
163
|
+
if options[:uniq] && (index = @target.index(record))
|
170
164
|
@target[index] = record
|
171
165
|
else
|
172
166
|
@target << record
|
@@ -177,7 +171,7 @@ module DatastaxRails
|
|
177
171
|
|
178
172
|
record
|
179
173
|
end
|
180
|
-
|
174
|
+
|
181
175
|
# Replace this collection with +other_array+
|
182
176
|
# This will perform a diff and delete/add only records that have changed.
|
183
177
|
def replace(other_array)
|
@@ -186,13 +180,13 @@ module DatastaxRails
|
|
186
180
|
|
187
181
|
delete(target - other_array)
|
188
182
|
|
189
|
-
unless concat(other_array - target)
|
183
|
+
unless concat(other_array - target) # rubocop:disable Style/GuardClause
|
190
184
|
@target = original_target
|
191
|
-
|
192
|
-
|
185
|
+
fail RecordNotSaved, "Failed to replace #{reflection.name} because one or more of the " \
|
186
|
+
'new records could not be saved.'
|
193
187
|
end
|
194
188
|
end
|
195
|
-
|
189
|
+
|
196
190
|
# Add +records+ to this association. Returns +self+ so method calls may be chained.
|
197
191
|
# Since << flattens its argument list and inserts each record, +push+ and +concat+ behave identically.
|
198
192
|
def concat(*records)
|
@@ -201,129 +195,129 @@ module DatastaxRails
|
|
201
195
|
|
202
196
|
records.flatten.each do |record|
|
203
197
|
raise_on_type_mismatch(record)
|
204
|
-
add_to_target(record) do |
|
198
|
+
add_to_target(record) do |_r|
|
205
199
|
result &&= insert_record(record) unless owner.new_record?
|
206
200
|
end
|
207
201
|
end
|
208
202
|
|
209
203
|
result && records
|
210
204
|
end
|
211
|
-
|
205
|
+
|
212
206
|
private
|
213
|
-
|
214
|
-
# We have some records loaded from the database (persisted) and some that are
|
215
|
-
# in-memory (memory). The same record may be represented in the persisted array
|
216
|
-
# and in the memory array.
|
217
|
-
#
|
218
|
-
# So the task of this method is to merge them according to the following rules:
|
219
|
-
#
|
220
|
-
# * The final array must not have duplicates
|
221
|
-
# * The order of the persisted array is to be preserved
|
222
|
-
# * Any changes made to attributes on objects in the memory array are to be preserved
|
223
|
-
# * Otherwise, attributes should have the value found in the database
|
224
|
-
def merge_target_lists(persisted, memory)
|
225
|
-
return persisted if memory.empty?
|
226
|
-
return memory if persisted.empty?
|
227
|
-
|
228
|
-
persisted.map! do |record|
|
229
|
-
# Unfortunately we cannot simply do memory.delete(record) since on 1.8 this returns
|
230
|
-
# record rather than memory.at(memory.index(record)). The behavior is fixed in 1.9.
|
231
|
-
mem_index = memory.index(record)
|
232
|
-
|
233
|
-
if mem_index
|
234
|
-
mem_record = memory.delete_at(mem_index)
|
235
|
-
|
236
|
-
(record.attribute_names - mem_record.changes.keys).each do |name|
|
237
|
-
mem_record[name] = record[name]
|
238
|
-
end
|
239
|
-
|
240
|
-
mem_record
|
241
|
-
else
|
242
|
-
record
|
243
|
-
end
|
244
|
-
end
|
245
207
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
end
|
208
|
+
# We have some records loaded from the database (persisted) and some that are
|
209
|
+
# in-memory (memory). The same record may be represented in the persisted array
|
210
|
+
# and in the memory array.
|
211
|
+
#
|
212
|
+
# So the task of this method is to merge them according to the following rules:
|
213
|
+
#
|
214
|
+
# * The final array must not have duplicates
|
215
|
+
# * The order of the persisted array is to be preserved
|
216
|
+
# * Any changes made to attributes on objects in the memory array are to be preserved
|
217
|
+
# * Otherwise, attributes should have the value found in the database
|
218
|
+
def merge_target_lists(persisted, memory)
|
219
|
+
return persisted if memory.empty?
|
220
|
+
return memory if persisted.empty?
|
260
221
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
222
|
+
persisted.map! do |record|
|
223
|
+
# Unfortunately we cannot simply do memory.delete(record) since on 1.8 this returns
|
224
|
+
# record rather than memory.at(memory.index(record)). The behavior is fixed in 1.9.
|
225
|
+
mem_index = memory.index(record)
|
226
|
+
|
227
|
+
if mem_index
|
228
|
+
mem_record = memory.delete_at(mem_index)
|
229
|
+
|
230
|
+
(record.attribute_names - mem_record.changes.keys).each do |name|
|
231
|
+
mem_record[name] = record[name]
|
267
232
|
end
|
233
|
+
|
234
|
+
mem_record
|
235
|
+
else
|
236
|
+
record
|
268
237
|
end
|
269
238
|
end
|
270
239
|
|
271
|
-
|
272
|
-
|
273
|
-
|
240
|
+
persisted + memory
|
241
|
+
end
|
242
|
+
|
243
|
+
def find_target
|
244
|
+
records = scoped.all
|
245
|
+
records = options[:uniq] ? uniq(records) : records
|
246
|
+
records.each { |record| set_inverse_instance(record) }
|
247
|
+
records
|
248
|
+
end
|
249
|
+
|
250
|
+
def create_record(attributes, options, raise = false, &block)
|
251
|
+
unless owner.persisted?
|
252
|
+
fail DatastaxRails::RecordNotSaved, 'You cannot call create unless the parent is saved'
|
274
253
|
end
|
275
|
-
|
276
|
-
|
277
|
-
|
254
|
+
|
255
|
+
if attributes.is_a?(Array)
|
256
|
+
attributes.map { |attr| create_record(attr, options, raise, &block) }
|
257
|
+
else
|
258
|
+
add_to_target(build_record(attributes, options)) do |record|
|
259
|
+
yield(record) if block_given?
|
260
|
+
insert_record(record, true, raise)
|
261
|
+
end
|
278
262
|
end
|
263
|
+
end
|
279
264
|
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
265
|
+
# Do the relevant stuff to insert the given record into the association collection.
|
266
|
+
def insert_record(_record, _validate = true, _raise = false)
|
267
|
+
fail NotImplementedError
|
268
|
+
end
|
284
269
|
|
285
|
-
|
270
|
+
def create_scope
|
271
|
+
scoped.scope_for_create.stringify_keys
|
272
|
+
end
|
286
273
|
|
287
|
-
|
288
|
-
|
274
|
+
def delete_or_destroy(records, method)
|
275
|
+
records = records.flatten
|
276
|
+
records.each { |record| raise_on_type_mismatch(record) }
|
277
|
+
existing_records = records.reject { |r| r.new_record? }
|
289
278
|
|
290
|
-
|
291
|
-
end
|
292
|
-
|
293
|
-
# Delete the given records from the association, using one of the methods :destroy,
|
294
|
-
# :delete_all or :nullify (or nil, in which case a default is used).
|
295
|
-
def delete_records(records, method)
|
296
|
-
raise NotImplementedError
|
297
|
-
end
|
279
|
+
records.each { |record| callback(:before_remove, record) }
|
298
280
|
|
299
|
-
|
300
|
-
|
301
|
-
case callback
|
302
|
-
when Symbol
|
303
|
-
owner.send(callback, record)
|
304
|
-
when Proc
|
305
|
-
callback.call(owner, record)
|
306
|
-
else
|
307
|
-
callback.send(method, owner, record)
|
308
|
-
end
|
309
|
-
end
|
310
|
-
end
|
281
|
+
delete_records(existing_records, method) if existing_records.any?
|
282
|
+
records.each { |record| target.delete(record) }
|
311
283
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
284
|
+
records.each { |record| callback(:after_remove, record) }
|
285
|
+
end
|
286
|
+
|
287
|
+
# Delete the given records from the association, using one of the methods :destroy,
|
288
|
+
# :delete_all or :nullify (or nil, in which case a default is used).
|
289
|
+
def delete_records(_records, _method)
|
290
|
+
fail NotImplementedError
|
291
|
+
end
|
292
|
+
|
293
|
+
def callback(method, record)
|
294
|
+
callbacks_for(method).each do |callback|
|
295
|
+
case callback
|
296
|
+
when Symbol
|
297
|
+
owner.send(callback, record)
|
298
|
+
when Proc
|
299
|
+
callback.call(owner, record)
|
323
300
|
else
|
324
|
-
|
301
|
+
callback.send(method, owner, record)
|
325
302
|
end
|
326
303
|
end
|
304
|
+
end
|
305
|
+
|
306
|
+
def callbacks_for(callback_name)
|
307
|
+
full_callback_name = "#{callback_name}_for_#{reflection.name}"
|
308
|
+
owner.class.send(full_callback_name.to_sym) || []
|
309
|
+
end
|
310
|
+
|
311
|
+
def include_in_memory?(record)
|
312
|
+
if reflection.is_a?(DatastaxRails::Reflection::ThroughReflection)
|
313
|
+
owner.send(reflection.through_reflection.name).any? do |source|
|
314
|
+
target = source.send(reflection.source_reflection.name)
|
315
|
+
target.respond_to?(:include?) ? target.include?(record) : target == record
|
316
|
+
end || target.include?(record)
|
317
|
+
else
|
318
|
+
target.include?(record)
|
319
|
+
end
|
320
|
+
end
|
327
321
|
end
|
328
322
|
end
|
329
|
-
end
|
323
|
+
end
|