datastax_rails 2.0.12 → 2.0.15
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eca5b1ed0b44ff67dffbe1c313ec3327b7011ac0
|
4
|
+
data.tar.gz: db1abc9e2a7c2577d7d20c8edf2492a81f88a2e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 919cf9003af455d8c2311b82801a8b3b2f33ef5fb004721c24128c6d76671207adc8ef2e6e4ea7961f14370bcd16846a53dc669956910757c7fc3b65f534a251
|
7
|
+
data.tar.gz: 2237e860f52576b248028d589a30773453783ccdf3e7c4bcb5bd688ff2b23064a7eed327805d06067931ecde65e0c7b7381a49df955a2c21a34f52eb8a668d1c
|
data/Rakefile
CHANGED
@@ -22,15 +22,15 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
22
22
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
23
23
|
end
|
24
24
|
|
25
|
-
APP_RAKEFILE = File.expand_path(
|
25
|
+
APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
|
26
26
|
load 'rails/tasks/engine.rake'
|
27
27
|
|
28
28
|
require 'rspec/core/rake_task'
|
29
29
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
30
|
-
#spec.rcov = true
|
31
|
-
#spec.rcov_opts = %w{--rails --exclude osx\/objc,gems\/,spec\/,features\/,cassandra_object\/}
|
32
|
-
spec.rspec_opts = File.read(File.expand_path(
|
30
|
+
# spec.rcov = true
|
31
|
+
# spec.rcov_opts = %w{--rails --exclude osx\/objc,gems\/,spec\/,features\/,cassandra_object\/}
|
32
|
+
spec.rspec_opts = File.read(File.expand_path('../spec/spec.opts', __FILE__)).split("\n")
|
33
33
|
end
|
34
|
-
task :
|
34
|
+
task default: :spec
|
35
35
|
|
36
36
|
Bundler::GemHelper.install_tasks
|
data/lib/blankslate.rb
CHANGED
@@ -15,17 +15,14 @@
|
|
15
15
|
# depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
|
16
16
|
class BlankSlate
|
17
17
|
class << self
|
18
|
-
|
19
18
|
# Hide the method named +name+ in the BlankSlate class. Don't
|
20
19
|
# hide +instance_eval+ or any method beginning with "__".
|
21
20
|
def hide(name)
|
22
21
|
methods = instance_methods.map(&:to_sym)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
undef_method name
|
28
|
-
end
|
22
|
+
return unless methods.include?(name.to_sym) && name !~ /^(__|instance_eval|object_id)/
|
23
|
+
@hidden_methods ||= {}
|
24
|
+
@hidden_methods[name.to_sym] = instance_method(name)
|
25
|
+
undef_method name
|
29
26
|
end
|
30
27
|
|
31
28
|
def find_hidden_method(name)
|
@@ -41,7 +38,7 @@ class BlankSlate
|
|
41
38
|
define_method(name, hidden_method)
|
42
39
|
end
|
43
40
|
end
|
44
|
-
|
41
|
+
|
45
42
|
instance_methods.each { |m| hide(m) }
|
46
43
|
end
|
47
44
|
|
@@ -81,7 +78,7 @@ class Object
|
|
81
78
|
result
|
82
79
|
end
|
83
80
|
|
84
|
-
def find_hidden_method(
|
81
|
+
def find_hidden_method(_name)
|
85
82
|
nil
|
86
83
|
end
|
87
84
|
end
|
@@ -94,7 +91,7 @@ end
|
|
94
91
|
# "feature" of Ruby prevents late includes into modules from being
|
95
92
|
# exposed in the first place.
|
96
93
|
class Module
|
97
|
-
|
94
|
+
alias_method :blankslate_original_append_features, :append_features
|
98
95
|
def append_features(mod)
|
99
96
|
result = blankslate_original_append_features(mod)
|
100
97
|
return result if mod != Object
|
@@ -103,4 +100,4 @@ class Module
|
|
103
100
|
end
|
104
101
|
result
|
105
102
|
end
|
106
|
-
end
|
103
|
+
end
|
data/lib/cql-rb_extensions.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# rubocop:disable Style/FileName
|
2
|
+
|
1
3
|
# By default, cql-rb grabs a random connection for each request. This is great for
|
2
4
|
# keeping load distributed across the cluster. Unfortunately, it plays havoc with
|
3
5
|
# the Solr integration where we often need to ensure that we're talking to the
|
@@ -8,9 +10,9 @@ require 'cql/client/connection_manager'
|
|
8
10
|
|
9
11
|
Cql::Client::ConnectionManager.class_eval do
|
10
12
|
attr_reader :current_connection
|
11
|
-
|
13
|
+
|
12
14
|
def random_connection
|
13
|
-
|
15
|
+
fail NotConnectedError unless connected?
|
14
16
|
@lock.synchronize do
|
15
17
|
@count ||= 0
|
16
18
|
@count += 1
|
@@ -29,4 +31,4 @@ Cql::Client::SynchronousClient.class_eval do
|
|
29
31
|
def current_connection
|
30
32
|
async.instance_variable_get(:@connection_manager).current_connection
|
31
33
|
end
|
32
|
-
end
|
34
|
+
end
|
@@ -18,10 +18,11 @@ module DatastaxRails
|
|
18
18
|
# HasManyAssociation
|
19
19
|
# HasManyThroughAssociation + ThroughAssociation (Not implemented)
|
20
20
|
class Association #:nodoc:
|
21
|
-
attr_reader :owner, :target, :reflection
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
attr_reader :owner, :target, :reflection, :loaded
|
22
|
+
alias_method :loaded?, :loaded
|
23
|
+
|
24
|
+
delegate :options, to: :reflection
|
25
|
+
|
25
26
|
def initialize(owner, reflection)
|
26
27
|
reflection.check_validity!
|
27
28
|
|
@@ -32,7 +33,7 @@ module DatastaxRails
|
|
32
33
|
reset
|
33
34
|
reset_scope
|
34
35
|
end
|
35
|
-
|
36
|
+
|
36
37
|
# Returns the name of the column family name of the related class:
|
37
38
|
#
|
38
39
|
# post.comments.aliased_column_family # => "comments"
|
@@ -40,13 +41,13 @@ module DatastaxRails
|
|
40
41
|
def aliased_column_family
|
41
42
|
reflection.klass.column_family
|
42
43
|
end
|
43
|
-
|
44
|
+
|
44
45
|
# Resets the \loaded flag to +false+ and sets the \target to +nil+.
|
45
46
|
def reset
|
46
47
|
@loaded = false
|
47
48
|
@target = nil
|
48
49
|
end
|
49
|
-
|
50
|
+
|
50
51
|
# Reloads the \target and returns +self+ on success.
|
51
52
|
def reload
|
52
53
|
reset
|
@@ -54,18 +55,13 @@ module DatastaxRails
|
|
54
55
|
load_target
|
55
56
|
self unless target.nil?
|
56
57
|
end
|
57
|
-
|
58
|
-
# Has the \target been already \loaded?
|
59
|
-
def loaded?
|
60
|
-
@loaded
|
61
|
-
end
|
62
|
-
|
58
|
+
|
63
59
|
# Asserts the \target has been loaded setting the \loaded flag to +true+.
|
64
60
|
def loaded!
|
65
61
|
@loaded = true
|
66
62
|
@stale_state = stale_state
|
67
63
|
end
|
68
|
-
|
64
|
+
|
69
65
|
# The target is stale if the target no longer points to the record(s) that the
|
70
66
|
# relevant foreign_key(s) refers to. If stale, the association accessor method
|
71
67
|
# on the owner will reload the target. It's up to subclasses to implement the
|
@@ -75,17 +71,17 @@ module DatastaxRails
|
|
75
71
|
def stale_target?
|
76
72
|
loaded? && @stale_state != stale_state
|
77
73
|
end
|
78
|
-
|
74
|
+
|
79
75
|
# Sets the target of this association to <tt>\target</tt>, and the \loaded flag to +true+.
|
80
76
|
def target=(target)
|
81
77
|
@target = target
|
82
78
|
loaded!
|
83
79
|
end
|
84
|
-
|
80
|
+
|
85
81
|
def scoped
|
86
82
|
target_scope.merge(association_scope)
|
87
83
|
end
|
88
|
-
|
84
|
+
|
89
85
|
# The scope for this association.
|
90
86
|
#
|
91
87
|
# Note that the association_scope is merged into the target_scope only when the
|
@@ -93,35 +89,32 @@ module DatastaxRails
|
|
93
89
|
# by scope.scoping { ... } or with_scope { ... } etc, which affects the scope which
|
94
90
|
# actually gets built.
|
95
91
|
def association_scope
|
96
|
-
if klass
|
97
|
-
@association_scope ||= AssociationScope.new(self).scope
|
98
|
-
end
|
92
|
+
@association_scope ||= AssociationScope.new(self).scope if klass
|
99
93
|
end
|
100
|
-
|
94
|
+
|
101
95
|
def reset_scope
|
102
96
|
@association_scope = nil
|
103
97
|
end
|
104
|
-
|
98
|
+
|
105
99
|
# Set the inverse association, if possible
|
106
|
-
def set_inverse_instance(record)
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
end
|
100
|
+
def set_inverse_instance(record) # rubocop:disable Style/AccessorMethodName
|
101
|
+
return unless record && invertible_for?(record)
|
102
|
+
inverse = record.association(inverse_reflection_for(record).name)
|
103
|
+
inverse.target = owner
|
111
104
|
end
|
112
|
-
|
105
|
+
|
113
106
|
# This class of the target. belongs_to polymorphic overrides this to look at the
|
114
107
|
# polymorphic_type field on the owner.
|
115
108
|
def klass
|
116
109
|
reflection.klass
|
117
110
|
end
|
118
|
-
|
111
|
+
|
119
112
|
# Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the
|
120
113
|
# through association's scope)
|
121
114
|
def target_scope
|
122
115
|
klass.scoped
|
123
116
|
end
|
124
|
-
|
117
|
+
|
125
118
|
# Loads the \target if needed and returns it.
|
126
119
|
#
|
127
120
|
# This method is abstract in the sense that it relies on +find_target+,
|
@@ -133,9 +126,7 @@ module DatastaxRails
|
|
133
126
|
# DatastaxRails::RecordNotFound is rescued within the method, and it is
|
134
127
|
# not reraised. The proxy is \reset and +nil+ is the return value.
|
135
128
|
def load_target
|
136
|
-
if find_target?
|
137
|
-
@target ||= find_target
|
138
|
-
end
|
129
|
+
@target ||= find_target if find_target?
|
139
130
|
loaded! unless loaded?
|
140
131
|
target
|
141
132
|
rescue DatastaxRails::RecordNotFound
|
@@ -143,79 +134,80 @@ module DatastaxRails
|
|
143
134
|
end
|
144
135
|
|
145
136
|
private
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
137
|
+
|
138
|
+
def find_target?
|
139
|
+
!loaded? && (!owner.new_record? || foreign_key_present?) && klass
|
140
|
+
end
|
141
|
+
|
142
|
+
def creation_attributes
|
143
|
+
{}.tap do |attributes|
|
144
|
+
if reflection.macro.in?([:has_one, :has_many]) && !options[:through]
|
145
|
+
attributes[reflection.foreign_key] = owner.id
|
146
|
+
|
147
|
+
# Note, polymorphic relationships are not implemented yet
|
148
|
+
if reflection.options[:as]
|
149
|
+
attributes[reflection.type] = owner.class.base_class.name
|
159
150
|
end
|
160
151
|
end
|
161
152
|
end
|
162
|
-
|
163
|
-
# Sets the owner attributes on the given record
|
164
|
-
def set_owner_attributes(record)
|
165
|
-
creation_attributes.each { |key, value| record[key] = value }
|
166
|
-
end
|
167
|
-
|
168
|
-
# Should be true if there is a foreign key present on the owner which
|
169
|
-
# references the target. This is used to determine whether we can load
|
170
|
-
# the target if the owner is currently a new record (and therefore
|
171
|
-
# without a key).
|
172
|
-
#
|
173
|
-
# Currently implemented by belongs_to (vanilla and polymorphic) and
|
174
|
-
# has_one/has_many :through associations which go through a belongs_to
|
175
|
-
def foreign_key_present?
|
176
|
-
false
|
177
|
-
end
|
178
|
-
|
179
|
-
# Raises DatastaxRails::AssociationTypeMismatch unless +record+ is of
|
180
|
-
# the kind of the class of the associated objects. Meant to be used as
|
181
|
-
# a sanity check when you are about to assign an associated record.
|
182
|
-
def raise_on_type_mismatch(record)
|
183
|
-
unless record.is_a?(reflection.klass) || record.is_a?(reflection.class_name.constantize)
|
184
|
-
message = "#{reflection.class_name}(##{reflection.klass.object_id}) expected, got #{record.class}(##{record.class.object_id})"
|
185
|
-
raise DatastaxRails::AssociationTypeMismatch, message
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
# Can be redefined by subclasses, notably polymorphic belongs_to
|
190
|
-
# The record parameter is necessary to support polymorphic inverses as we must check for
|
191
|
-
# the association in the specific class of the record.
|
192
|
-
def inverse_reflection_for(record)
|
193
|
-
reflection.inverse_of
|
194
|
-
end
|
195
|
-
|
196
|
-
# Is this association invertible? Can be redefined by subclasses.
|
197
|
-
def invertible_for?(record)
|
198
|
-
inverse_reflection_for(record)
|
199
|
-
end
|
200
|
-
|
201
|
-
# This should be implemented to return the values of the relevant key(s) on the owner,
|
202
|
-
# so that when state_state is different from the value stored on the last find_target,
|
203
|
-
# the target is stale.
|
204
|
-
#
|
205
|
-
# This is only relevant to certain associations, which is why it returns nil by default.
|
206
|
-
def stale_state
|
207
|
-
nil
|
208
|
-
end
|
209
|
-
|
210
|
-
def association_class
|
211
|
-
@reflection.klass
|
212
|
-
end
|
153
|
+
end
|
213
154
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
155
|
+
# Sets the owner attributes on the given record
|
156
|
+
def set_owner_attributes(record) # rubocop:disable Style/AccessorMethodName
|
157
|
+
creation_attributes.each { |key, value| record[key] = value }
|
158
|
+
end
|
159
|
+
|
160
|
+
# Should be true if there is a foreign key present on the owner which
|
161
|
+
# references the target. This is used to determine whether we can load
|
162
|
+
# the target if the owner is currently a new record (and therefore
|
163
|
+
# without a key).
|
164
|
+
#
|
165
|
+
# Currently implemented by belongs_to (vanilla and polymorphic) and
|
166
|
+
# has_one/has_many :through associations which go through a belongs_to
|
167
|
+
def foreign_key_present?
|
168
|
+
false
|
169
|
+
end
|
170
|
+
|
171
|
+
# Raises DatastaxRails::AssociationTypeMismatch unless +record+ is of
|
172
|
+
# the kind of the class of the associated objects. Meant to be used as
|
173
|
+
# a sanity check when you are about to assign an associated record.
|
174
|
+
def raise_on_type_mismatch(record)
|
175
|
+
return if record.is_a?(reflection.klass) || record.is_a?(reflection.class_name.constantize)
|
176
|
+
message = "#{reflection.class_name}(##{reflection.klass.object_id}) expected," \
|
177
|
+
" got #{record.class}(##{record.class.object_id})"
|
178
|
+
fail DatastaxRails::AssociationTypeMismatch, message
|
179
|
+
end
|
180
|
+
|
181
|
+
# Can be redefined by subclasses, notably polymorphic belongs_to
|
182
|
+
# The record parameter is necessary to support polymorphic inverses as we must check for
|
183
|
+
# the association in the specific class of the record.
|
184
|
+
def inverse_reflection_for(_record)
|
185
|
+
reflection.inverse_of
|
186
|
+
end
|
187
|
+
|
188
|
+
# Is this association invertible? Can be redefined by subclasses.
|
189
|
+
def invertible_for?(record)
|
190
|
+
inverse_reflection_for(record)
|
191
|
+
end
|
192
|
+
|
193
|
+
# This should be implemented to return the values of the relevant key(s) on the owner,
|
194
|
+
# so that when state_state is different from the value stored on the last find_target,
|
195
|
+
# the target is stale.
|
196
|
+
#
|
197
|
+
# This is only relevant to certain associations, which is why it returns nil by default.
|
198
|
+
def stale_state
|
199
|
+
nil
|
200
|
+
end
|
201
|
+
|
202
|
+
def association_class
|
203
|
+
@reflection.klass
|
204
|
+
end
|
205
|
+
|
206
|
+
def build_record(attributes, options)
|
207
|
+
reflection.build_association(attributes, options) do |r|
|
208
|
+
r.assign_attributes(create_scope.except(*r.changed))
|
218
209
|
end
|
210
|
+
end
|
219
211
|
end
|
220
212
|
end
|
221
213
|
end
|
@@ -2,18 +2,18 @@ module DatastaxRails
|
|
2
2
|
module Associations
|
3
3
|
class AssociationScope #:nodoc:
|
4
4
|
attr_reader :association
|
5
|
-
|
6
|
-
delegate :klass, :owner, :reflection, :
|
7
|
-
delegate :chain, :options, :datastax_rails, :
|
8
|
-
|
5
|
+
|
6
|
+
delegate :klass, :owner, :reflection, to: :association
|
7
|
+
delegate :chain, :options, :datastax_rails, to: :reflection
|
8
|
+
|
9
9
|
def initialize(association)
|
10
10
|
@association = association
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def scope
|
14
14
|
scope = klass.unscoped
|
15
15
|
scope = scope.extending(*Array.wrap(options[:extend]))
|
16
|
-
|
16
|
+
|
17
17
|
if reflection.source_macro == :belongs_to
|
18
18
|
scope.where('id' => owner.send(reflection.foreign_key))
|
19
19
|
else
|
@@ -22,4 +22,4 @@ module DatastaxRails
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
25
|
-
end
|
25
|
+
end
|
@@ -1,65 +1,63 @@
|
|
1
1
|
module DatastaxRails
|
2
2
|
module Associations
|
3
3
|
class BelongsToAssociation < SingularAssociation #:nodoc:
|
4
|
+
attr_reader :updated
|
5
|
+
alias_method :updated?, :updated
|
4
6
|
def replace(record)
|
5
7
|
raise_on_type_mismatch(record) if record
|
6
|
-
|
8
|
+
|
7
9
|
replace_keys(record)
|
8
10
|
set_inverse_instance(record)
|
9
|
-
|
11
|
+
|
10
12
|
@updated = true if record
|
11
|
-
|
13
|
+
|
12
14
|
self.target = record
|
13
15
|
end
|
14
|
-
|
15
|
-
def updated?
|
16
|
-
@updated
|
17
|
-
end
|
18
|
-
|
16
|
+
|
19
17
|
private
|
20
|
-
|
21
|
-
def find_target?
|
22
|
-
!loaded? && foreign_key_present? && klass
|
23
|
-
end
|
24
|
-
|
25
|
-
# Checks whether record is different to the current target, without loading it
|
26
|
-
def different_target?(record)
|
27
|
-
record.nil? && owner[reflection.foreign_key] ||
|
28
|
-
record && record.id != owner[reflection.foreign_key]
|
29
|
-
end
|
30
|
-
|
31
|
-
def replace_keys(record)
|
32
|
-
owner.loaded_attributes[reflection.foreign_key] = true
|
33
|
-
owner.send("#{reflection.foreign_key}_will_change!")
|
34
|
-
if record
|
35
|
-
owner[reflection.foreign_key] = record.id
|
36
|
-
else
|
37
|
-
owner[reflection.foreign_key] = nil
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def foreign_key_present?
|
42
|
-
owner[reflection.foreign_key]
|
43
|
-
end
|
44
|
-
|
45
|
-
# NOTE - for now, we're only supporting inverse setting from belongs_to back onto
|
46
|
-
# has_one associations.
|
47
|
-
def invertible_for?(record)
|
48
|
-
inverse = inverse_reflection_for(record)
|
49
|
-
inverse && inverse.macro == :has_one
|
50
|
-
end
|
51
18
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
19
|
+
def find_target?
|
20
|
+
!loaded? && foreign_key_present? && klass
|
21
|
+
end
|
22
|
+
|
23
|
+
# Checks whether record is different to the current target, without loading it
|
24
|
+
def different_target?(record)
|
25
|
+
record.nil? && owner[reflection.foreign_key] ||
|
26
|
+
record && record.id != owner[reflection.foreign_key]
|
27
|
+
end
|
28
|
+
|
29
|
+
def replace_keys(record)
|
30
|
+
owner.loaded_attributes[reflection.foreign_key] = true
|
31
|
+
owner.send("#{reflection.foreign_key}_will_change!")
|
32
|
+
if record
|
33
|
+
owner[reflection.foreign_key] = record.id
|
34
|
+
else
|
35
|
+
owner[reflection.foreign_key] = nil
|
58
36
|
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def foreign_key_present?
|
40
|
+
owner[reflection.foreign_key]
|
41
|
+
end
|
59
42
|
|
60
|
-
|
61
|
-
|
43
|
+
# NOTE - for now, we're only supporting inverse setting from belongs_to back onto
|
44
|
+
# has_one associations.
|
45
|
+
def invertible_for?(record)
|
46
|
+
inverse = inverse_reflection_for(record)
|
47
|
+
inverse && inverse.macro == :has_one
|
48
|
+
end
|
49
|
+
|
50
|
+
def target_id
|
51
|
+
if options[:primary_key]
|
52
|
+
owner.send(reflection.name).try(:id)
|
53
|
+
else
|
54
|
+
owner[reflection.foreign_key]
|
62
55
|
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def stale_state
|
59
|
+
owner[reflection.foreign_key].to_s
|
60
|
+
end
|
63
61
|
end
|
64
62
|
end
|
65
|
-
end
|
63
|
+
end
|