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.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +5 -5
  3. data/lib/blankslate.rb +8 -11
  4. data/lib/cql-rb_extensions.rb +5 -3
  5. data/lib/datastax_rails/associations/association.rb +93 -101
  6. data/lib/datastax_rails/associations/association_scope.rb +7 -7
  7. data/lib/datastax_rails/associations/belongs_to_association.rb +46 -48
  8. data/lib/datastax_rails/associations/builder/association.rb +32 -31
  9. data/lib/datastax_rails/associations/builder/belongs_to.rb +19 -20
  10. data/lib/datastax_rails/associations/builder/collection_association.rb +32 -32
  11. data/lib/datastax_rails/associations/builder/has_and_belongs_to_many.rb +21 -21
  12. data/lib/datastax_rails/associations/builder/has_many.rb +39 -40
  13. data/lib/datastax_rails/associations/builder/has_one.rb +30 -31
  14. data/lib/datastax_rails/associations/builder/singular_association.rb +31 -33
  15. data/lib/datastax_rails/associations/collection_association.rb +129 -135
  16. data/lib/datastax_rails/associations/collection_proxy.rb +21 -21
  17. data/lib/datastax_rails/associations/has_and_belongs_to_many_association.rb +26 -26
  18. data/lib/datastax_rails/associations/has_many_association.rb +38 -38
  19. data/lib/datastax_rails/associations/has_one_association.rb +31 -32
  20. data/lib/datastax_rails/associations/singular_association.rb +31 -30
  21. data/lib/datastax_rails/associations.rb +27 -24
  22. data/lib/datastax_rails/attribute_assignment.rb +17 -17
  23. data/lib/datastax_rails/attribute_methods/definition.rb +4 -4
  24. data/lib/datastax_rails/attribute_methods/dirty.rb +34 -33
  25. data/lib/datastax_rails/attribute_methods/primary_key.rb +3 -8
  26. data/lib/datastax_rails/attribute_methods/read.rb +10 -12
  27. data/lib/datastax_rails/attribute_methods/typecasting.rb +36 -35
  28. data/lib/datastax_rails/attribute_methods/write.rb +5 -6
  29. data/lib/datastax_rails/attribute_methods.rb +52 -56
  30. data/lib/datastax_rails/base.rb +122 -125
  31. data/lib/datastax_rails/callbacks.rb +15 -9
  32. data/lib/datastax_rails/cassandra_only_model.rb +6 -6
  33. data/lib/datastax_rails/collection.rb +5 -7
  34. data/lib/datastax_rails/column.rb +130 -118
  35. data/lib/datastax_rails/connection/statement_cache.rb +3 -3
  36. data/lib/datastax_rails/connection.rb +42 -33
  37. data/lib/datastax_rails/cql/alter_column_family.rb +19 -21
  38. data/lib/datastax_rails/cql/base.rb +8 -11
  39. data/lib/datastax_rails/cql/column_family.rb +11 -10
  40. data/lib/datastax_rails/cql/consistency.rb +2 -2
  41. data/lib/datastax_rails/cql/create_column_family.rb +15 -15
  42. data/lib/datastax_rails/cql/create_index.rb +5 -5
  43. data/lib/datastax_rails/cql/create_keyspace.rb +7 -7
  44. data/lib/datastax_rails/cql/delete.rb +16 -29
  45. data/lib/datastax_rails/cql/drop_column_family.rb +2 -2
  46. data/lib/datastax_rails/cql/drop_index.rb +2 -2
  47. data/lib/datastax_rails/cql/drop_keyspace.rb +2 -2
  48. data/lib/datastax_rails/cql/insert.rb +10 -16
  49. data/lib/datastax_rails/cql/select.rb +21 -33
  50. data/lib/datastax_rails/cql/truncate.rb +2 -2
  51. data/lib/datastax_rails/cql/update.rb +16 -24
  52. data/lib/datastax_rails/cql/use_keyspace.rb +2 -2
  53. data/lib/datastax_rails/cql.rb +2 -2
  54. data/lib/datastax_rails/dynamic_model.rb +32 -29
  55. data/lib/datastax_rails/errors.rb +6 -6
  56. data/lib/datastax_rails/grouped_collection.rb +3 -3
  57. data/lib/datastax_rails/inheritance.rb +9 -9
  58. data/lib/datastax_rails/payload_model.rb +24 -20
  59. data/lib/datastax_rails/persistence.rb +116 -110
  60. data/lib/datastax_rails/railtie.rb +7 -7
  61. data/lib/datastax_rails/reflection.rb +61 -59
  62. data/lib/datastax_rails/relation/batches.rb +12 -13
  63. data/lib/datastax_rails/relation/facet_methods.rb +44 -33
  64. data/lib/datastax_rails/relation/finder_methods.rb +95 -91
  65. data/lib/datastax_rails/relation/modification_methods.rb +5 -5
  66. data/lib/datastax_rails/relation/search_methods.rb +102 -102
  67. data/lib/datastax_rails/relation/spawn_methods.rb +25 -24
  68. data/lib/datastax_rails/relation/stats_methods.rb +9 -8
  69. data/lib/datastax_rails/relation.rb +165 -170
  70. data/lib/datastax_rails/rsolr_client_wrapper.rb +3 -3
  71. data/lib/datastax_rails/schema/cassandra.rb +44 -43
  72. data/lib/datastax_rails/schema/migrator.rb +52 -52
  73. data/lib/datastax_rails/schema/solr.rb +55 -47
  74. data/lib/datastax_rails/schema_cache.rb +1 -3
  75. data/lib/datastax_rails/scoping/default.rb +2 -3
  76. data/lib/datastax_rails/scoping/named.rb +3 -5
  77. data/lib/datastax_rails/scoping.rb +11 -12
  78. data/lib/datastax_rails/serialization.rb +34 -31
  79. data/lib/datastax_rails/serializers/xml_serializer.rb +178 -175
  80. data/lib/datastax_rails/timestamps.rb +4 -4
  81. data/lib/datastax_rails/types/dirty_collection.rb +57 -57
  82. data/lib/datastax_rails/types/dynamic_list.rb +1 -1
  83. data/lib/datastax_rails/types/dynamic_map.rb +5 -7
  84. data/lib/datastax_rails/types/dynamic_set.rb +2 -2
  85. data/lib/datastax_rails/util/solr_repair.rb +3 -3
  86. data/lib/datastax_rails/validations/associated.rb +8 -6
  87. data/lib/datastax_rails/validations/uniqueness.rb +8 -8
  88. data/lib/datastax_rails/validations.rb +9 -10
  89. data/lib/datastax_rails/version.rb +2 -1
  90. data/lib/datastax_rails/wide_storage_model.rb +6 -6
  91. data/lib/datastax_rails.rb +13 -9
  92. data/lib/schema_migration.rb +3 -3
  93. data/spec/datastax_rails/associations/belongs_to_association_spec.rb +2 -2
  94. data/spec/datastax_rails/associations/collection_association_spec.rb +14 -14
  95. data/spec/datastax_rails/associations/has_many_association_spec.rb +20 -20
  96. data/spec/datastax_rails/associations_spec.rb +11 -11
  97. data/spec/datastax_rails/attribute_methods_spec.rb +25 -25
  98. data/spec/datastax_rails/base_spec.rb +24 -24
  99. data/spec/datastax_rails/callbacks_spec.rb +21 -21
  100. data/spec/datastax_rails/column_spec.rb +133 -132
  101. data/spec/datastax_rails/connection/statement_cache_spec.rb +2 -2
  102. data/spec/datastax_rails/cql/base_spec.rb +4 -4
  103. data/spec/datastax_rails/cql/delete_spec.rb +19 -0
  104. data/spec/datastax_rails/cql/select_spec.rb +8 -8
  105. data/spec/datastax_rails/cql/update_spec.rb +8 -10
  106. data/spec/datastax_rails/dynamic_model_spec.rb +36 -22
  107. data/spec/datastax_rails/inheritance_spec.rb +11 -14
  108. data/spec/datastax_rails/persistence_spec.rb +73 -74
  109. data/spec/datastax_rails/relation/batches_spec.rb +13 -13
  110. data/spec/datastax_rails/relation/facet_methods_spec.rb +43 -35
  111. data/spec/datastax_rails/relation/finder_methods_spec.rb +77 -78
  112. data/spec/datastax_rails/relation/modification_methods_spec.rb +19 -19
  113. data/spec/datastax_rails/relation/search_methods_spec.rb +160 -160
  114. data/spec/datastax_rails/relation/spawn_methods_spec.rb +18 -18
  115. data/spec/datastax_rails/relation_spec.rb +119 -116
  116. data/spec/datastax_rails/schema/migrator_spec.rb +30 -30
  117. data/spec/datastax_rails/schema/solr_spec.rb +15 -15
  118. data/spec/datastax_rails/scoping/default_spec.rb +9 -9
  119. data/spec/datastax_rails/types/dynamic_list_spec.rb +12 -12
  120. data/spec/datastax_rails/types/dynamic_map_spec.rb +10 -10
  121. data/spec/datastax_rails/types/dynamic_set_spec.rb +22 -10
  122. data/spec/datastax_rails/validations/uniqueness_spec.rb +25 -25
  123. data/spec/datastax_rails/wide_storage_model_spec.rb +11 -0
  124. data/spec/datastax_rails_spec.rb +2 -2
  125. data/spec/dummy/config/application.rb +2 -3
  126. data/spec/dummy/config/boot.rb +1 -1
  127. data/spec/dummy/config/environments/development.rb +3 -3
  128. data/spec/dummy/config/environments/test.rb +1 -1
  129. data/spec/dummy/config/initializers/session_store.rb +1 -1
  130. data/spec/dummy/config/initializers/wrap_parameters.rb +1 -1
  131. data/spec/factories/audit_logs.rb +6 -0
  132. data/spec/factories/hobbies.rb +6 -0
  133. data/spec/factories/people.rb +5 -0
  134. data/spec/feature/dynamic_fields_spec.rb +4 -4
  135. data/spec/feature/overloaded_tables_spec.rb +11 -12
  136. data/spec/spec_helper.rb +17 -14
  137. data/spec/support/datastax_test_hook.rb +2 -2
  138. data/spec/support/default_consistency_shared_examples.rb +11 -11
  139. data/spec/support/models.rb +31 -32
  140. metadata +40 -6
  141. data/lib/datastax_rails/attribute_methods/before_type_cast.rb +0 -71
  142. data/lib/datastax_rails/log_subscriber.rb +0 -0
  143. 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: 98234dcb77c32791b630e27d4a9e4deb0be11068
4
- data.tar.gz: 0faf451aa7dfb597651ef4195d0849731ac43b7e
3
+ metadata.gz: eca5b1ed0b44ff67dffbe1c313ec3327b7011ac0
4
+ data.tar.gz: db1abc9e2a7c2577d7d20c8edf2492a81f88a2e2
5
5
  SHA512:
6
- metadata.gz: 6b0ca26bcaedfe88407c54badf618eb8968aa2cdbda4aac273c7d0422be89d79ce2b806af36d0bdebb41e8ad40a67a86c806065bec014ceb3d39ecf7a9ade7bf
7
- data.tar.gz: 9a502e20649c2e627bf4256e4e175860ef3004cd3fe6d418a0506c343ca2c8cb6eee8702a19aeef75d1cd10a7ed6b616f48e138bc933c24bbb002890cce95d78
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("../spec/dummy/Rakefile", __FILE__)
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("../spec/spec.opts", __FILE__)).split("\n")
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 :default => :spec
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
- if methods.include?(name.to_sym) and
24
- name !~ /^(__|instance_eval|object_id)/
25
- @hidden_methods ||= {}
26
- @hidden_methods[name.to_sym] = instance_method(name)
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(name)
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
- alias blankslate_original_append_features append_features
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
@@ -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
- raise NotConnectedError unless connected?
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
- delegate :options, :to => :reflection
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
- if record && invertible_for?(record)
108
- inverse = record.association(inverse_reflection_for(record).name)
109
- inverse.target = owner
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
- def find_target?
147
- !loaded? && (!owner.new_record? || foreign_key_present?) && klass
148
- end
149
-
150
- def creation_attributes
151
- {}.tap do |attributes|
152
- if reflection.macro.in?([:has_one, :has_many]) && !options[:through]
153
- attributes[reflection.foreign_key] = owner.id
154
-
155
- # Note, polymorphic relationships are not implemented yet
156
- if reflection.options[:as]
157
- attributes[reflection.type] = owner.class.base_class.name
158
- end
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
- def build_record(attributes, options)
215
- reflection.build_association(attributes, options) do |r|
216
- r.assign_attributes(create_scope.except(*r.changed))
217
- end
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, :to => :association
7
- delegate :chain, :options, :datastax_rails, :to => :reflection
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
- def target_id
53
- if options[:primary_key]
54
- owner.send(reflection.name).try(:id)
55
- else
56
- owner[reflection.foreign_key]
57
- end
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
- def stale_state
61
- owner[reflection.foreign_key].to_s
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