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.
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
@@ -12,9 +12,7 @@ module DatastaxRails
12
12
  end
13
13
 
14
14
  @columns_hash = Hash.new do |h, table_name|
15
- h[table_name] = Hash[columns[table_name].map { |col|
16
- [col.name, col]
17
- }]
15
+ h[table_name] = Hash[columns[table_name].map { |col| [col.name, col] }]
18
16
  end
19
17
 
20
18
  @primary_keys = Hash.new do |h, table_name|
@@ -7,7 +7,7 @@ module DatastaxRails
7
7
 
8
8
  included do
9
9
  # Stores the default scope for the class
10
- class_attribute :default_scopes, :instance_writer => false
10
+ class_attribute :default_scopes, instance_writer: false
11
11
  self.default_scopes = []
12
12
  end
13
13
 
@@ -102,7 +102,7 @@ module DatastaxRails
102
102
  evaluate_default_scope { default_scope }
103
103
  elsif default_scopes.any?
104
104
  evaluate_default_scope do
105
- default_scopes.inject(relation) do |default_scope, scope|
105
+ default_scopes.reduce(relation) do |default_scope, scope|
106
106
  if scope.is_a?(Hash)
107
107
  default_scope.apply_finder_options(scope)
108
108
  elsif !scope.is_a?(Relation) && scope.respond_to?(:call)
@@ -135,7 +135,6 @@ module DatastaxRails
135
135
  self.ignore_default_scope = false
136
136
  end
137
137
  end
138
-
139
138
  end
140
139
  end
141
140
  end
@@ -186,13 +186,11 @@ module DatastaxRails
186
186
  singleton_class.send(:redefine_method, name, &scope_proc)
187
187
  end
188
188
 
189
- protected
189
+ protected
190
190
 
191
191
  def valid_scope_name?(name)
192
- if logger && respond_to?(name, true)
193
- logger.warn "Creating scope :#{name}. " \
194
- "Overwriting existing method #{self.name}.#{name}."
195
- end
192
+ logger && respond_to?(name, true) &&
193
+ logger.warn("Creating scope :#{name}. Overwriting existing method #{self.name}.#{name}.")
196
194
  end
197
195
  end
198
196
  end
@@ -57,11 +57,10 @@ module DatastaxRails
57
57
  # end
58
58
  #
59
59
  # *Note*: the +:find+ scope also has effect on update and deletion methods, like +update_all+ and +delete_all+.
60
- def with_scope(scope = {}, action = :merge, &block)
60
+ def with_scope(scope = {}, action = :merge, &_block) # rubocop:disable Style/CyclomaticComplexity
61
61
  # If another DatastaxRails class has been passed in, get its current scope
62
62
  scope = scope.current_scope if !scope.is_a?(Relation) && scope.respond_to?(:current_scope)
63
-
64
- previous_scope = self.current_scope
63
+ previous_scope = current_scope
65
64
 
66
65
  if scope.is_a?(Hash)
67
66
  # Dup first and second level of hash (method and params).
@@ -70,16 +69,16 @@ module DatastaxRails
70
69
  scope[method] = params.dup unless params == true
71
70
  end
72
71
 
73
- scope.assert_valid_keys([ :find, :create ])
72
+ scope.assert_valid_keys([:find, :create])
74
73
  relation = construct_finder_arel(scope[:find] || {})
75
74
  relation.default_scoped = true unless action == :overwrite
76
75
 
77
76
  if previous_scope && previous_scope.create_with_value && scope[:create]
78
77
  scope_for_create = if action == :merge
79
- previous_scope.create_with_value.merge(scope[:create])
80
- else
81
- scope[:create]
82
- end
78
+ previous_scope.create_with_value.merge(scope[:create])
79
+ else
80
+ scope[:create]
81
+ end
83
82
 
84
83
  relation = relation.create_with(scope_for_create)
85
84
  else
@@ -106,8 +105,9 @@ module DatastaxRails
106
105
  # Works like with_scope, but discards any nested properties.
107
106
  def with_exclusive_scope(method_scoping = {}, &block)
108
107
  if method_scoping.values.any? { |e| e.is_a?(DatastaxRails::Relation) }
109
- raise ArgumentError, <<-MSG
110
- New finder API can not be used with_exclusive_scope. You can either call unscoped to get an anonymous scope not bound to the default_scope:
108
+ fail ArgumentError, <<-MSG
109
+ New finder API can not be used with_exclusive_scope. You can either call unscoped to get
110
+ an anonymous scope not bound to the default_scope:
111
111
 
112
112
  User.unscoped.where(:active => true)
113
113
 
@@ -137,13 +137,12 @@ module DatastaxRails
137
137
  relation = scope.merge(relation) if scope
138
138
  relation
139
139
  end
140
-
141
140
  end
142
141
 
143
142
  def populate_with_current_scope_attributes
144
143
  return unless self.class.scope_attributes?
145
144
 
146
- self.class.scope_attributes.each do |att,value|
145
+ self.class.scope_attributes.each do |att, value|
147
146
  send("#{att}=", value) if respond_to?("#{att}=")
148
147
  end
149
148
  end
@@ -12,52 +12,55 @@ module DatastaxRails
12
12
  hash = super(options)
13
13
 
14
14
  serializable_add_includes(options) do |association, records, opts|
15
- hash[association] = records.is_a?(Enumerable) ?
16
- records.map { |r| r.serializable_hash(opts) } :
17
- records.serializable_hash(opts)
15
+ hash[association] = if records.is_a?(Enumerable)
16
+ records.map { |r| r.serializable_hash(opts) }
17
+ else
18
+ records.serializable_hash(opts)
19
+ end
18
20
  end
19
21
 
20
22
  hash
21
23
  end
22
-
24
+
23
25
  def as_json(options = {})
24
26
  json = super(options)
25
- json.each {|k,v| json[k] = v.to_s if v.is_a?(::Cql::Uuid)}
27
+ json.each { |k, v| json[k] = v.to_s if v.is_a?(::Cql::Uuid) }
26
28
  end
27
29
 
28
30
  private
29
- # Add associations specified via the <tt>:include</tt> option.
30
- #
31
- # Expects a block that takes as arguments:
32
- # +association+ - name of the association
33
- # +records+ - the association record(s) to be serialized
34
- # +opts+ - options for the association records
35
- def serializable_add_includes(options = {})
36
- return unless include_associations = options.delete(:include)
37
31
 
38
- base_only_or_except = { :except => options[:except],
39
- :only => options[:only] }
32
+ # Add associations specified via the <tt>:include</tt> option.
33
+ #
34
+ # Expects a block that takes as arguments:
35
+ # +association+ - name of the association
36
+ # +records+ - the association record(s) to be serialized
37
+ # +opts+ - options for the association records
38
+ def serializable_add_includes(options = {})
39
+ include_associations = options.delete(:include)
40
+ return unless include_associations
40
41
 
41
- include_has_options = include_associations.is_a?(Hash)
42
- associations = include_has_options ? include_associations.keys : Array.wrap(include_associations)
42
+ base_only_or_except = { except: options[:except],
43
+ only: options[:only] }
43
44
 
44
- associations.each do |association|
45
- records = case self.class.reflect_on_association(association).macro
46
- when :has_many, :has_and_belongs_to_many
47
- send(association).to_a
48
- when :has_one, :belongs_to
49
- send(association)
50
- end
45
+ include_has_options = include_associations.is_a?(Hash)
46
+ associations = include_has_options ? include_associations.keys : Array.wrap(include_associations)
51
47
 
52
- if records
53
- association_options = include_has_options ? include_associations[association] : base_only_or_except
54
- opts = options.merge(association_options)
55
- yield(association, records, opts)
56
- end
57
- end
48
+ associations.each do |association|
49
+ records = case self.class.reflect_on_association(association).macro
50
+ when :has_many, :has_and_belongs_to_many
51
+ send(association).to_a
52
+ when :has_one, :belongs_to
53
+ send(association)
54
+ end
58
55
 
59
- options[:include] = include_associations
56
+ next unless records
57
+ association_options = include_has_options ? include_associations[association] : base_only_or_except
58
+ opts = options.merge(association_options)
59
+ yield(association, records, opts)
60
60
  end
61
+
62
+ options[:include] = include_associations
63
+ end
61
64
  end
62
65
  end
63
66
 
@@ -2,175 +2,176 @@ require 'active_support/core_ext/array/wrap'
2
2
  require 'active_support/core_ext/hash/conversions'
3
3
 
4
4
  module DatastaxRails
5
+ # Builds an XML document to represent the model. Some configuration is
6
+ # available through +options+. However more complicated cases should
7
+ # override DatastaxRails::Base#to_xml.
8
+ #
9
+ # By default the generated XML document will include the processing
10
+ # instruction and all the object's attributes. For example:
11
+ #
12
+ # <?xml version="1.0" encoding="UTF-8"?>
13
+ # <topic>
14
+ # <title>The First Topic</title>
15
+ # <author-name>David</author-name>
16
+ # <id type="integer">1</id>
17
+ # <approved type="boolean">false</approved>
18
+ # <replies-count type="integer">0</replies-count>
19
+ # <bonus-time type="datetime">2000-01-01T08:28:00+12:00</bonus-time>
20
+ # <written-on type="datetime">2003-07-16T09:28:00+1200</written-on>
21
+ # <content>Have a nice day</content>
22
+ # <author-email-address>david@loudthinking.com</author-email-address>
23
+ # <parent-id></parent-id>
24
+ # <last-read type="date">2004-04-15</last-read>
25
+ # </topic>
26
+ #
27
+ # This behavior can be controlled with <tt>:only</tt>, <tt>:except</tt>,
28
+ # <tt>:skip_instruct</tt>, <tt>:skip_types</tt>, <tt>:dasherize</tt> and <tt>:camelize</tt> .
29
+ # The <tt>:only</tt> and <tt>:except</tt> options are the same as for the
30
+ # +attributes+ method. The default is to dasherize all column names, but you
31
+ # can disable this setting <tt>:dasherize</tt> to +false+. Setting <tt>:camelize</tt>
32
+ # to +true+ will camelize all column names - this also overrides <tt>:dasherize</tt>.
33
+ # To not have the column type included in the XML output set <tt>:skip_types</tt> to +true+.
34
+ #
35
+ # For instance:
36
+ #
37
+ # topic.to_xml(:skip_instruct => true, :except => [ :id, :bonus_time, :written_on, :replies_count ])
38
+ #
39
+ # <topic>
40
+ # <title>The First Topic</title>
41
+ # <author-name>David</author-name>
42
+ # <approved type="boolean">false</approved>
43
+ # <content>Have a nice day</content>
44
+ # <author-email-address>david@loudthinking.com</author-email-address>
45
+ # <parent-id></parent-id>
46
+ # <last-read type="date">2004-04-15</last-read>
47
+ # </topic>
48
+ #
49
+ # To include first level associations use <tt>:include</tt>:
50
+ #
51
+ # firm.to_xml :include => [ :account, :clients ]
52
+ #
53
+ # <?xml version="1.0" encoding="UTF-8"?>
54
+ # <firm>
55
+ # <id type="integer">1</id>
56
+ # <rating type="integer">1</rating>
57
+ # <name>37signals</name>
58
+ # <clients type="array">
59
+ # <client>
60
+ # <rating type="integer">1</rating>
61
+ # <name>Summit</name>
62
+ # </client>
63
+ # <client>
64
+ # <rating type="integer">1</rating>
65
+ # <name>Microsoft</name>
66
+ # </client>
67
+ # </clients>
68
+ # <account>
69
+ # <id type="integer">1</id>
70
+ # <credit-limit type="integer">50</credit-limit>
71
+ # </account>
72
+ # </firm>
73
+ #
74
+ # Additionally, the record being serialized will be passed to a Proc's second
75
+ # parameter. This allows for ad hoc additions to the resultant document that
76
+ # incorporate the context of the record being serialized. And by leveraging the
77
+ # closure created by a Proc, to_xml can be used to add elements that normally fall
78
+ # outside of the scope of the model -- for example, generating and appending URLs
79
+ # associated with models.
80
+ #
81
+ # proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
82
+ # firm.to_xml :procs => [ proc ]
83
+ #
84
+ # <firm>
85
+ # # ... normal attributes as shown above ...
86
+ # <name-reverse>slangis73</name-reverse>
87
+ # </firm>
88
+ #
89
+ # To include deeper levels of associations pass a hash like this:
90
+ #
91
+ # firm.to_xml :include => {:account => {}, :clients => {:include => :address}}
92
+ # <?xml version="1.0" encoding="UTF-8"?>
93
+ # <firm>
94
+ # <id type="integer">1</id>
95
+ # <rating type="integer">1</rating>
96
+ # <name>37signals</name>
97
+ # <clients type="array">
98
+ # <client>
99
+ # <rating type="integer">1</rating>
100
+ # <name>Summit</name>
101
+ # <address>
102
+ # ...
103
+ # </address>
104
+ # </client>
105
+ # <client>
106
+ # <rating type="integer">1</rating>
107
+ # <name>Microsoft</name>
108
+ # <address>
109
+ # ...
110
+ # </address>
111
+ # </client>
112
+ # </clients>
113
+ # <account>
114
+ # <id type="integer">1</id>
115
+ # <credit-limit type="integer">50</credit-limit>
116
+ # </account>
117
+ # </firm>
118
+ #
119
+ # To include any methods on the model being called use <tt>:methods</tt>:
120
+ #
121
+ # firm.to_xml :methods => [ :calculated_earnings, :real_earnings ]
122
+ #
123
+ # <firm>
124
+ # # ... normal attributes as shown above ...
125
+ # <calculated-earnings>100000000000000000</calculated-earnings>
126
+ # <real-earnings>5</real-earnings>
127
+ # </firm>
128
+ #
129
+ # To call any additional Procs use <tt>:procs</tt>. The Procs are passed a
130
+ # modified version of the options hash that was given to +to_xml+:
131
+ #
132
+ # proc = Proc.new { |options| options[:builder].tag!('abc', 'def') }
133
+ # firm.to_xml :procs => [ proc ]
134
+ #
135
+ # <firm>
136
+ # # ... normal attributes as shown above ...
137
+ # <abc>def</abc>
138
+ # </firm>
139
+ #
140
+ # Alternatively, you can yield the builder object as part of the +to_xml+ call:
141
+ #
142
+ # firm.to_xml do |xml|
143
+ # xml.creator do
144
+ # xml.first_name "David"
145
+ # xml.last_name "Heinemeier Hansson"
146
+ # end
147
+ # end
148
+ #
149
+ # <firm>
150
+ # # ... normal attributes as shown above ...
151
+ # <creator>
152
+ # <first_name>David</first_name>
153
+ # <last_name>Heinemeier Hansson</last_name>
154
+ # </creator>
155
+ # </firm>
156
+ #
157
+ # As noted above, you may override +to_xml+ in your DatastaxRails::Base
158
+ # subclasses to have complete control about what's generated. The general
159
+ # form of doing this is:
160
+ #
161
+ # class IHaveMyOwnXML < DatastaxRails::Base
162
+ # def to_xml(options = {})
163
+ # options[:indent] ||= 2
164
+ # xml = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
165
+ # xml.instruct! unless options[:skip_instruct]
166
+ # xml.level_one do
167
+ # xml.tag!(:second_level, 'content')
168
+ # end
169
+ # end
170
+ # end
5
171
  module Serialization
6
172
  include ActiveModel::Serializers::Xml
7
173
 
8
- # Builds an XML document to represent the model. Some configuration is
9
- # available through +options+. However more complicated cases should
10
- # override DatastaxRails::Base#to_xml.
11
- #
12
- # By default the generated XML document will include the processing
13
- # instruction and all the object's attributes. For example:
14
- #
15
- # <?xml version="1.0" encoding="UTF-8"?>
16
- # <topic>
17
- # <title>The First Topic</title>
18
- # <author-name>David</author-name>
19
- # <id type="integer">1</id>
20
- # <approved type="boolean">false</approved>
21
- # <replies-count type="integer">0</replies-count>
22
- # <bonus-time type="datetime">2000-01-01T08:28:00+12:00</bonus-time>
23
- # <written-on type="datetime">2003-07-16T09:28:00+1200</written-on>
24
- # <content>Have a nice day</content>
25
- # <author-email-address>david@loudthinking.com</author-email-address>
26
- # <parent-id></parent-id>
27
- # <last-read type="date">2004-04-15</last-read>
28
- # </topic>
29
- #
30
- # This behavior can be controlled with <tt>:only</tt>, <tt>:except</tt>,
31
- # <tt>:skip_instruct</tt>, <tt>:skip_types</tt>, <tt>:dasherize</tt> and <tt>:camelize</tt> .
32
- # The <tt>:only</tt> and <tt>:except</tt> options are the same as for the
33
- # +attributes+ method. The default is to dasherize all column names, but you
34
- # can disable this setting <tt>:dasherize</tt> to +false+. Setting <tt>:camelize</tt>
35
- # to +true+ will camelize all column names - this also overrides <tt>:dasherize</tt>.
36
- # To not have the column type included in the XML output set <tt>:skip_types</tt> to +true+.
37
- #
38
- # For instance:
39
- #
40
- # topic.to_xml(:skip_instruct => true, :except => [ :id, :bonus_time, :written_on, :replies_count ])
41
- #
42
- # <topic>
43
- # <title>The First Topic</title>
44
- # <author-name>David</author-name>
45
- # <approved type="boolean">false</approved>
46
- # <content>Have a nice day</content>
47
- # <author-email-address>david@loudthinking.com</author-email-address>
48
- # <parent-id></parent-id>
49
- # <last-read type="date">2004-04-15</last-read>
50
- # </topic>
51
- #
52
- # To include first level associations use <tt>:include</tt>:
53
- #
54
- # firm.to_xml :include => [ :account, :clients ]
55
- #
56
- # <?xml version="1.0" encoding="UTF-8"?>
57
- # <firm>
58
- # <id type="integer">1</id>
59
- # <rating type="integer">1</rating>
60
- # <name>37signals</name>
61
- # <clients type="array">
62
- # <client>
63
- # <rating type="integer">1</rating>
64
- # <name>Summit</name>
65
- # </client>
66
- # <client>
67
- # <rating type="integer">1</rating>
68
- # <name>Microsoft</name>
69
- # </client>
70
- # </clients>
71
- # <account>
72
- # <id type="integer">1</id>
73
- # <credit-limit type="integer">50</credit-limit>
74
- # </account>
75
- # </firm>
76
- #
77
- # Additionally, the record being serialized will be passed to a Proc's second
78
- # parameter. This allows for ad hoc additions to the resultant document that
79
- # incorporate the context of the record being serialized. And by leveraging the
80
- # closure created by a Proc, to_xml can be used to add elements that normally fall
81
- # outside of the scope of the model -- for example, generating and appending URLs
82
- # associated with models.
83
- #
84
- # proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
85
- # firm.to_xml :procs => [ proc ]
86
- #
87
- # <firm>
88
- # # ... normal attributes as shown above ...
89
- # <name-reverse>slangis73</name-reverse>
90
- # </firm>
91
- #
92
- # To include deeper levels of associations pass a hash like this:
93
- #
94
- # firm.to_xml :include => {:account => {}, :clients => {:include => :address}}
95
- # <?xml version="1.0" encoding="UTF-8"?>
96
- # <firm>
97
- # <id type="integer">1</id>
98
- # <rating type="integer">1</rating>
99
- # <name>37signals</name>
100
- # <clients type="array">
101
- # <client>
102
- # <rating type="integer">1</rating>
103
- # <name>Summit</name>
104
- # <address>
105
- # ...
106
- # </address>
107
- # </client>
108
- # <client>
109
- # <rating type="integer">1</rating>
110
- # <name>Microsoft</name>
111
- # <address>
112
- # ...
113
- # </address>
114
- # </client>
115
- # </clients>
116
- # <account>
117
- # <id type="integer">1</id>
118
- # <credit-limit type="integer">50</credit-limit>
119
- # </account>
120
- # </firm>
121
- #
122
- # To include any methods on the model being called use <tt>:methods</tt>:
123
- #
124
- # firm.to_xml :methods => [ :calculated_earnings, :real_earnings ]
125
- #
126
- # <firm>
127
- # # ... normal attributes as shown above ...
128
- # <calculated-earnings>100000000000000000</calculated-earnings>
129
- # <real-earnings>5</real-earnings>
130
- # </firm>
131
- #
132
- # To call any additional Procs use <tt>:procs</tt>. The Procs are passed a
133
- # modified version of the options hash that was given to +to_xml+:
134
- #
135
- # proc = Proc.new { |options| options[:builder].tag!('abc', 'def') }
136
- # firm.to_xml :procs => [ proc ]
137
- #
138
- # <firm>
139
- # # ... normal attributes as shown above ...
140
- # <abc>def</abc>
141
- # </firm>
142
- #
143
- # Alternatively, you can yield the builder object as part of the +to_xml+ call:
144
- #
145
- # firm.to_xml do |xml|
146
- # xml.creator do
147
- # xml.first_name "David"
148
- # xml.last_name "Heinemeier Hansson"
149
- # end
150
- # end
151
- #
152
- # <firm>
153
- # # ... normal attributes as shown above ...
154
- # <creator>
155
- # <first_name>David</first_name>
156
- # <last_name>Heinemeier Hansson</last_name>
157
- # </creator>
158
- # </firm>
159
- #
160
- # As noted above, you may override +to_xml+ in your DatastaxRails::Base
161
- # subclasses to have complete control about what's generated. The general
162
- # form of doing this is:
163
- #
164
- # class IHaveMyOwnXML < DatastaxRails::Base
165
- # def to_xml(options = {})
166
- # options[:indent] ||= 2
167
- # xml = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
168
- # xml.instruct! unless options[:skip_instruct]
169
- # xml.level_one do
170
- # xml.tag!(:second_level, 'content')
171
- # end
172
- # end
173
- # end
174
+ # See the module level documentation for an example of +to_xml+.
174
175
  def to_xml(options = {}, &block)
175
176
  options[:methods] ||= []
176
177
  options[:methods] << :id
@@ -179,7 +180,8 @@ module DatastaxRails
179
180
  end
180
181
  end
181
182
 
182
- class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc:
183
+ # Implementation of ActiveModel's XML Serializer
184
+ class XmlSerializer < ActiveModel::Serializers::Xml::Serializer
183
185
  def initialize(*args)
184
186
  super
185
187
  end
@@ -196,14 +198,14 @@ module DatastaxRails
196
198
  options[:procs] = procs
197
199
  end
198
200
 
199
- # TODO This can likely be cleaned up to simple use ActiveSupport::XmlMini.to_tag as well.
201
+ # TODO: This can likely be cleaned up to simple use ActiveSupport::XmlMini.to_tag as well.
200
202
  def add_associations(association, records, opts)
201
203
  association_name = association.to_s.singularize
202
- merged_options = options.merge(opts).merge!(:root => association_name, :skip_instruct => true)
204
+ merged_options = options.merge(opts).merge!(root: association_name, skip_instruct: true)
203
205
 
204
206
  if records.is_a?(Enumerable)
205
207
  tag = ActiveSupport::XmlMini.rename_key(association.to_s, options)
206
- type = options[:skip_types] ? { } : {:type => "array"}
208
+ type = options[:skip_types] ? {} : { type: 'array' }
207
209
 
208
210
  if records.empty?
209
211
  @builder.tag!(tag, type)
@@ -214,19 +216,20 @@ module DatastaxRails
214
216
  record_type = {}
215
217
  else
216
218
  record_class = (record.class.to_s.underscore == association_name) ? nil : record.class.name
217
- record_type = {:type => record_class}
219
+ record_type = { type: record_class }
218
220
  end
219
221
 
220
222
  record.to_xml merged_options.merge(record_type)
221
223
  end
222
224
  end
223
225
  end
224
- elsif record = @serializable.send(association)
226
+ elsif (record = @serializable.send(association))
225
227
  record.to_xml(merged_options)
226
228
  end
227
229
  end
228
230
 
229
- class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc:
231
+ # Implementation of ActiveModel's XML Serializer Attribute
232
+ class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute
230
233
  def compute_type
231
234
  klass = @serializable.class
232
235
  type = if klass.serialized_attributes.key?(name.to_sym)
@@ -237,8 +240,8 @@ module DatastaxRails
237
240
  NilClass
238
241
  end
239
242
 
240
- { :text => :string,
241
- :time => :datetime }[type] || type
243
+ { text: :string,
244
+ time: :datetime }[type] || type
242
245
  end
243
246
  protected :compute_type
244
247
  end