activerecord 3.2.19 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (264) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1715 -604
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +40 -45
  5. data/examples/performance.rb +33 -22
  6. data/examples/simple.rb +3 -4
  7. data/lib/active_record/aggregations.rb +76 -51
  8. data/lib/active_record/association_relation.rb +35 -0
  9. data/lib/active_record/associations/alias_tracker.rb +54 -40
  10. data/lib/active_record/associations/association.rb +76 -56
  11. data/lib/active_record/associations/association_scope.rb +125 -93
  12. data/lib/active_record/associations/belongs_to_association.rb +57 -28
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -2
  14. data/lib/active_record/associations/builder/association.rb +120 -32
  15. data/lib/active_record/associations/builder/belongs_to.rb +115 -62
  16. data/lib/active_record/associations/builder/collection_association.rb +61 -53
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +117 -43
  18. data/lib/active_record/associations/builder/has_many.rb +9 -65
  19. data/lib/active_record/associations/builder/has_one.rb +18 -52
  20. data/lib/active_record/associations/builder/singular_association.rb +18 -19
  21. data/lib/active_record/associations/collection_association.rb +268 -186
  22. data/lib/active_record/associations/collection_proxy.rb +1003 -63
  23. data/lib/active_record/associations/foreign_association.rb +11 -0
  24. data/lib/active_record/associations/has_many_association.rb +81 -41
  25. data/lib/active_record/associations/has_many_through_association.rb +76 -55
  26. data/lib/active_record/associations/has_one_association.rb +51 -21
  27. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  28. data/lib/active_record/associations/join_dependency/join_association.rb +83 -108
  29. data/lib/active_record/associations/join_dependency/join_base.rb +7 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +30 -37
  31. data/lib/active_record/associations/join_dependency.rb +239 -155
  32. data/lib/active_record/associations/preloader/association.rb +97 -62
  33. data/lib/active_record/associations/preloader/collection_association.rb +2 -8
  34. data/lib/active_record/associations/preloader/has_many_through.rb +7 -3
  35. data/lib/active_record/associations/preloader/has_one.rb +0 -8
  36. data/lib/active_record/associations/preloader/singular_association.rb +3 -3
  37. data/lib/active_record/associations/preloader/through_association.rb +75 -33
  38. data/lib/active_record/associations/preloader.rb +111 -79
  39. data/lib/active_record/associations/singular_association.rb +35 -13
  40. data/lib/active_record/associations/through_association.rb +41 -19
  41. data/lib/active_record/associations.rb +727 -501
  42. data/lib/active_record/attribute/user_provided_default.rb +28 -0
  43. data/lib/active_record/attribute.rb +213 -0
  44. data/lib/active_record/attribute_assignment.rb +32 -162
  45. data/lib/active_record/attribute_decorators.rb +67 -0
  46. data/lib/active_record/attribute_methods/before_type_cast.rb +52 -7
  47. data/lib/active_record/attribute_methods/dirty.rb +101 -61
  48. data/lib/active_record/attribute_methods/primary_key.rb +50 -36
  49. data/lib/active_record/attribute_methods/query.rb +7 -6
  50. data/lib/active_record/attribute_methods/read.rb +56 -117
  51. data/lib/active_record/attribute_methods/serialization.rb +43 -96
  52. data/lib/active_record/attribute_methods/time_zone_conversion.rb +93 -42
  53. data/lib/active_record/attribute_methods/write.rb +34 -45
  54. data/lib/active_record/attribute_methods.rb +333 -144
  55. data/lib/active_record/attribute_mutation_tracker.rb +70 -0
  56. data/lib/active_record/attribute_set/builder.rb +108 -0
  57. data/lib/active_record/attribute_set.rb +108 -0
  58. data/lib/active_record/attributes.rb +265 -0
  59. data/lib/active_record/autosave_association.rb +285 -223
  60. data/lib/active_record/base.rb +95 -490
  61. data/lib/active_record/callbacks.rb +95 -61
  62. data/lib/active_record/coders/json.rb +13 -0
  63. data/lib/active_record/coders/yaml_column.rb +28 -19
  64. data/lib/active_record/collection_cache_key.rb +40 -0
  65. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +724 -277
  66. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  67. data/lib/active_record/connection_adapters/abstract/database_statements.rb +199 -192
  68. data/lib/active_record/connection_adapters/abstract/query_cache.rb +31 -26
  69. data/lib/active_record/connection_adapters/abstract/quoting.rb +140 -57
  70. data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
  71. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +147 -0
  72. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +419 -276
  73. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +105 -0
  74. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +963 -276
  75. data/lib/active_record/connection_adapters/abstract/transaction.rb +232 -0
  76. data/lib/active_record/connection_adapters/abstract_adapter.rb +397 -106
  77. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +643 -342
  78. data/lib/active_record/connection_adapters/column.rb +30 -259
  79. data/lib/active_record/connection_adapters/connection_specification.rb +263 -0
  80. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
  81. data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
  82. data/lib/active_record/connection_adapters/mysql/database_statements.rb +125 -0
  83. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
  84. data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
  85. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +67 -0
  86. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +93 -0
  87. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -0
  88. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
  89. data/lib/active_record/connection_adapters/mysql2_adapter.rb +47 -196
  90. data/lib/active_record/connection_adapters/postgresql/column.rb +15 -0
  91. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +170 -0
  92. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +70 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +52 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +13 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +15 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +48 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +21 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +19 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +59 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +13 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +10 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +39 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +93 -0
  109. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +15 -0
  110. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +109 -0
  111. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +21 -0
  112. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +26 -0
  113. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +28 -0
  114. data/lib/active_record/connection_adapters/postgresql/oid.rb +31 -0
  115. data/lib/active_record/connection_adapters/postgresql/quoting.rb +116 -0
  116. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +49 -0
  117. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +180 -0
  118. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +47 -0
  119. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +682 -0
  120. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
  121. data/lib/active_record/connection_adapters/postgresql/utils.rb +77 -0
  122. data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -1039
  123. data/lib/active_record/connection_adapters/schema_cache.rb +74 -36
  124. data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
  125. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
  126. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
  127. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  128. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +538 -24
  129. data/lib/active_record/connection_adapters/statement_pool.rb +31 -12
  130. data/lib/active_record/connection_handling.rb +155 -0
  131. data/lib/active_record/core.rb +561 -0
  132. data/lib/active_record/counter_cache.rb +146 -105
  133. data/lib/active_record/dynamic_matchers.rb +101 -64
  134. data/lib/active_record/enum.rb +234 -0
  135. data/lib/active_record/errors.rb +153 -56
  136. data/lib/active_record/explain.rb +15 -63
  137. data/lib/active_record/explain_registry.rb +30 -0
  138. data/lib/active_record/explain_subscriber.rb +10 -6
  139. data/lib/active_record/fixture_set/file.rb +77 -0
  140. data/lib/active_record/fixtures.rb +355 -232
  141. data/lib/active_record/gem_version.rb +15 -0
  142. data/lib/active_record/inheritance.rb +144 -79
  143. data/lib/active_record/integration.rb +66 -13
  144. data/lib/active_record/internal_metadata.rb +56 -0
  145. data/lib/active_record/legacy_yaml_adapter.rb +46 -0
  146. data/lib/active_record/locale/en.yml +9 -1
  147. data/lib/active_record/locking/optimistic.rb +77 -56
  148. data/lib/active_record/locking/pessimistic.rb +6 -6
  149. data/lib/active_record/log_subscriber.rb +53 -28
  150. data/lib/active_record/migration/command_recorder.rb +166 -33
  151. data/lib/active_record/migration/compatibility.rb +126 -0
  152. data/lib/active_record/migration/join_table.rb +15 -0
  153. data/lib/active_record/migration.rb +792 -264
  154. data/lib/active_record/model_schema.rb +192 -130
  155. data/lib/active_record/nested_attributes.rb +238 -145
  156. data/lib/active_record/no_touching.rb +52 -0
  157. data/lib/active_record/null_relation.rb +89 -0
  158. data/lib/active_record/persistence.rb +357 -157
  159. data/lib/active_record/query_cache.rb +22 -43
  160. data/lib/active_record/querying.rb +34 -23
  161. data/lib/active_record/railtie.rb +88 -48
  162. data/lib/active_record/railties/console_sandbox.rb +3 -4
  163. data/lib/active_record/railties/controller_runtime.rb +5 -4
  164. data/lib/active_record/railties/databases.rake +170 -422
  165. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  166. data/lib/active_record/readonly_attributes.rb +2 -5
  167. data/lib/active_record/reflection.rb +715 -189
  168. data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
  169. data/lib/active_record/relation/batches.rb +203 -50
  170. data/lib/active_record/relation/calculations.rb +203 -194
  171. data/lib/active_record/relation/delegation.rb +103 -25
  172. data/lib/active_record/relation/finder_methods.rb +457 -261
  173. data/lib/active_record/relation/from_clause.rb +32 -0
  174. data/lib/active_record/relation/merger.rb +167 -0
  175. data/lib/active_record/relation/predicate_builder/array_handler.rb +43 -0
  176. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +88 -0
  177. data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
  178. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
  179. data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
  180. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
  181. data/lib/active_record/relation/predicate_builder/range_handler.rb +33 -0
  182. data/lib/active_record/relation/predicate_builder/relation_handler.rb +13 -0
  183. data/lib/active_record/relation/predicate_builder.rb +153 -48
  184. data/lib/active_record/relation/query_attribute.rb +19 -0
  185. data/lib/active_record/relation/query_methods.rb +1019 -194
  186. data/lib/active_record/relation/record_fetch_warning.rb +49 -0
  187. data/lib/active_record/relation/spawn_methods.rb +46 -150
  188. data/lib/active_record/relation/where_clause.rb +174 -0
  189. data/lib/active_record/relation/where_clause_factory.rb +38 -0
  190. data/lib/active_record/relation.rb +450 -245
  191. data/lib/active_record/result.rb +104 -12
  192. data/lib/active_record/runtime_registry.rb +22 -0
  193. data/lib/active_record/sanitization.rb +120 -94
  194. data/lib/active_record/schema.rb +28 -18
  195. data/lib/active_record/schema_dumper.rb +141 -74
  196. data/lib/active_record/schema_migration.rb +50 -0
  197. data/lib/active_record/scoping/default.rb +64 -57
  198. data/lib/active_record/scoping/named.rb +93 -108
  199. data/lib/active_record/scoping.rb +73 -121
  200. data/lib/active_record/secure_token.rb +38 -0
  201. data/lib/active_record/serialization.rb +7 -5
  202. data/lib/active_record/statement_cache.rb +113 -0
  203. data/lib/active_record/store.rb +173 -15
  204. data/lib/active_record/suppressor.rb +58 -0
  205. data/lib/active_record/table_metadata.rb +68 -0
  206. data/lib/active_record/tasks/database_tasks.rb +313 -0
  207. data/lib/active_record/tasks/mysql_database_tasks.rb +151 -0
  208. data/lib/active_record/tasks/postgresql_database_tasks.rb +110 -0
  209. data/lib/active_record/tasks/sqlite_database_tasks.rb +59 -0
  210. data/lib/active_record/timestamp.rb +42 -24
  211. data/lib/active_record/touch_later.rb +58 -0
  212. data/lib/active_record/transactions.rb +233 -105
  213. data/lib/active_record/type/adapter_specific_registry.rb +130 -0
  214. data/lib/active_record/type/date.rb +7 -0
  215. data/lib/active_record/type/date_time.rb +7 -0
  216. data/lib/active_record/type/hash_lookup_type_map.rb +23 -0
  217. data/lib/active_record/type/internal/abstract_json.rb +29 -0
  218. data/lib/active_record/type/internal/timezone.rb +15 -0
  219. data/lib/active_record/type/serialized.rb +63 -0
  220. data/lib/active_record/type/time.rb +20 -0
  221. data/lib/active_record/type/type_map.rb +64 -0
  222. data/lib/active_record/type.rb +72 -0
  223. data/lib/active_record/type_caster/connection.rb +29 -0
  224. data/lib/active_record/type_caster/map.rb +19 -0
  225. data/lib/active_record/type_caster.rb +7 -0
  226. data/lib/active_record/validations/absence.rb +23 -0
  227. data/lib/active_record/validations/associated.rb +33 -18
  228. data/lib/active_record/validations/length.rb +24 -0
  229. data/lib/active_record/validations/presence.rb +66 -0
  230. data/lib/active_record/validations/uniqueness.rb +128 -68
  231. data/lib/active_record/validations.rb +48 -40
  232. data/lib/active_record/version.rb +5 -7
  233. data/lib/active_record.rb +71 -47
  234. data/lib/rails/generators/active_record/migration/migration_generator.rb +56 -8
  235. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +24 -0
  236. data/lib/rails/generators/active_record/migration/templates/migration.rb +28 -16
  237. data/lib/rails/generators/active_record/migration.rb +18 -8
  238. data/lib/rails/generators/active_record/model/model_generator.rb +38 -16
  239. data/lib/rails/generators/active_record/model/templates/application_record.rb +5 -0
  240. data/lib/rails/generators/active_record/model/templates/model.rb +7 -6
  241. data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
  242. data/lib/rails/generators/active_record.rb +3 -11
  243. metadata +188 -134
  244. data/examples/associations.png +0 -0
  245. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
  246. data/lib/active_record/associations/join_helper.rb +0 -55
  247. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
  248. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  249. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
  250. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -441
  251. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
  252. data/lib/active_record/dynamic_finder_match.rb +0 -68
  253. data/lib/active_record/dynamic_scope_match.rb +0 -23
  254. data/lib/active_record/fixtures/file.rb +0 -65
  255. data/lib/active_record/identity_map.rb +0 -162
  256. data/lib/active_record/observer.rb +0 -121
  257. data/lib/active_record/serializers/xml_serializer.rb +0 -203
  258. data/lib/active_record/session_store.rb +0 -360
  259. data/lib/active_record/test_case.rb +0 -73
  260. data/lib/rails/generators/active_record/model/templates/migration.rb +0 -15
  261. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  262. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  263. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  264. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,65 +0,0 @@
1
- begin
2
- require 'psych'
3
- rescue LoadError
4
- end
5
-
6
- require 'erb'
7
- require 'yaml'
8
-
9
- module ActiveRecord
10
- class Fixtures
11
- class File
12
- include Enumerable
13
-
14
- ##
15
- # Open a fixture file named +file+. When called with a block, the block
16
- # is called with the filehandle and the filehandle is automatically closed
17
- # when the block finishes.
18
- def self.open(file)
19
- x = new file
20
- block_given? ? yield(x) : x
21
- end
22
-
23
- def initialize(file)
24
- @file = file
25
- @rows = nil
26
- end
27
-
28
- def each(&block)
29
- rows.each(&block)
30
- end
31
-
32
- RESCUE_ERRORS = [ ArgumentError ] # :nodoc:
33
-
34
- private
35
- if defined?(Psych) && defined?(Psych::SyntaxError)
36
- RESCUE_ERRORS << Psych::SyntaxError
37
- end
38
-
39
- def rows
40
- return @rows if @rows
41
-
42
- begin
43
- data = YAML.load(render(IO.read(@file)))
44
- rescue *RESCUE_ERRORS => error
45
- raise Fixture::FormatError, "a YAML error occurred parsing #{@file}. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html\nThe exact error was:\n #{error.class}: #{error}", error.backtrace
46
- end
47
- @rows = data ? validate(data).to_a : []
48
- end
49
-
50
- def render(content)
51
- ERB.new(content).result
52
- end
53
-
54
- # Validate our unmarshalled data.
55
- def validate(data)
56
- unless Hash === data || YAML::Omap === data
57
- raise Fixture::FormatError, 'fixture is not a hash'
58
- end
59
-
60
- raise Fixture::FormatError unless data.all? { |name, row| Hash === row }
61
- data
62
- end
63
- end
64
- end
65
- end
@@ -1,162 +0,0 @@
1
- module ActiveRecord
2
- # = Active Record Identity Map
3
- #
4
- # Ensures that each object gets loaded only once by keeping every loaded
5
- # object in a map. Looks up objects using the map when referring to them.
6
- #
7
- # More information on Identity Map pattern:
8
- # http://www.martinfowler.com/eaaCatalog/identityMap.html
9
- #
10
- # == Configuration
11
- #
12
- # In order to enable IdentityMap, set <tt>config.active_record.identity_map = true</tt>
13
- # in your <tt>config/application.rb</tt> file.
14
- #
15
- # IdentityMap is disabled by default and still in development (i.e. use it with care).
16
- #
17
- # == Associations
18
- #
19
- # Active Record Identity Map does not track associations yet. For example:
20
- #
21
- # comment = @post.comments.first
22
- # comment.post = nil
23
- # @post.comments.include?(comment) #=> true
24
- #
25
- # Ideally, the example above would return false, removing the comment object from the
26
- # post association when the association is nullified. This may cause side effects, as
27
- # in the situation below, if Identity Map is enabled:
28
- #
29
- # Post.has_many :comments, :dependent => :destroy
30
- #
31
- # comment = @post.comments.first
32
- # comment.post = nil
33
- # comment.save
34
- # Post.destroy(@post.id)
35
- #
36
- # Without using Identity Map, the code above will destroy the @post object leaving
37
- # the comment object intact. However, once we enable Identity Map, the post loaded
38
- # by Post.destroy is exactly the same object as the object @post. As the object @post
39
- # still has the comment object in @post.comments, once Identity Map is enabled, the
40
- # comment object will be accidently removed.
41
- #
42
- # This inconsistency is meant to be fixed in future Rails releases.
43
- #
44
- module IdentityMap
45
-
46
- class << self
47
- def enabled=(flag)
48
- Thread.current[:identity_map_enabled] = flag
49
- end
50
-
51
- def enabled
52
- Thread.current[:identity_map_enabled]
53
- end
54
- alias enabled? enabled
55
-
56
- def repository
57
- Thread.current[:identity_map] ||= Hash.new { |h,k| h[k] = {} }
58
- end
59
-
60
- def use
61
- old, self.enabled = enabled, true
62
-
63
- yield if block_given?
64
- ensure
65
- self.enabled = old
66
- clear
67
- end
68
-
69
- def without
70
- old, self.enabled = enabled, false
71
-
72
- yield if block_given?
73
- ensure
74
- self.enabled = old
75
- end
76
-
77
- def get(klass, primary_key)
78
- record = repository[klass.symbolized_sti_name][primary_key]
79
-
80
- if record.is_a?(klass)
81
- ActiveSupport::Notifications.instrument("identity.active_record",
82
- :line => "From Identity Map (id: #{primary_key})",
83
- :name => "#{klass} Loaded",
84
- :connection_id => object_id)
85
-
86
- record
87
- else
88
- nil
89
- end
90
- end
91
-
92
- def add(record)
93
- repository[record.class.symbolized_sti_name][record.id] = record if contain_all_columns?(record)
94
- end
95
-
96
- def remove(record)
97
- repository[record.class.symbolized_sti_name].delete(record.id)
98
- end
99
-
100
- def remove_by_id(symbolized_sti_name, id)
101
- repository[symbolized_sti_name].delete(id)
102
- end
103
-
104
- def clear
105
- repository.clear
106
- end
107
-
108
- private
109
-
110
- def contain_all_columns?(record)
111
- (record.class.column_names - record.attribute_names).empty?
112
- end
113
- end
114
-
115
- # Reinitialize an Identity Map model object from +coder+.
116
- # +coder+ must contain the attributes necessary for initializing an empty
117
- # model object.
118
- def reinit_with(coder)
119
- @attributes_cache = {}
120
- dirty = @changed_attributes.keys
121
- attributes = self.class.initialize_attributes(coder['attributes'].except(*dirty))
122
- @attributes.update(attributes)
123
- @changed_attributes.update(coder['attributes'].slice(*dirty))
124
- @changed_attributes.delete_if{|k,v| v.eql? @attributes[k]}
125
-
126
- run_callbacks :find
127
-
128
- self
129
- end
130
-
131
- class Middleware
132
- class Body #:nodoc:
133
- def initialize(target, original)
134
- @target = target
135
- @original = original
136
- end
137
-
138
- def each(&block)
139
- @target.each(&block)
140
- end
141
-
142
- def close
143
- @target.close if @target.respond_to?(:close)
144
- ensure
145
- IdentityMap.enabled = @original
146
- IdentityMap.clear
147
- end
148
- end
149
-
150
- def initialize(app)
151
- @app = app
152
- end
153
-
154
- def call(env)
155
- enabled = IdentityMap.enabled
156
- IdentityMap.enabled = true
157
- status, headers, body = @app.call(env)
158
- [status, headers, Body.new(body, enabled)]
159
- end
160
- end
161
- end
162
- end
@@ -1,121 +0,0 @@
1
- require 'active_support/core_ext/class/attribute'
2
-
3
- module ActiveRecord
4
- # = Active Record Observer
5
- #
6
- # Observer classes respond to life cycle callbacks to implement trigger-like
7
- # behavior outside the original class. This is a great way to reduce the
8
- # clutter that normally comes when the model class is burdened with
9
- # functionality that doesn't pertain to the core responsibility of the
10
- # class. Example:
11
- #
12
- # class CommentObserver < ActiveRecord::Observer
13
- # def after_save(comment)
14
- # Notifications.comment("admin@do.com", "New comment was posted", comment).deliver
15
- # end
16
- # end
17
- #
18
- # This Observer sends an email when a Comment#save is finished.
19
- #
20
- # class ContactObserver < ActiveRecord::Observer
21
- # def after_create(contact)
22
- # contact.logger.info('New contact added!')
23
- # end
24
- #
25
- # def after_destroy(contact)
26
- # contact.logger.warn("Contact with an id of #{contact.id} was destroyed!")
27
- # end
28
- # end
29
- #
30
- # This Observer uses logger to log when specific callbacks are triggered.
31
- #
32
- # == Observing a class that can't be inferred
33
- #
34
- # Observers will by default be mapped to the class with which they share a name. So CommentObserver will
35
- # be tied to observing Comment, ProductManagerObserver to ProductManager, and so on. If you want to name your observer
36
- # differently than the class you're interested in observing, you can use the Observer.observe class method which takes
37
- # either the concrete class (Product) or a symbol for that class (:product):
38
- #
39
- # class AuditObserver < ActiveRecord::Observer
40
- # observe :account
41
- #
42
- # def after_update(account)
43
- # AuditTrail.new(account, "UPDATED")
44
- # end
45
- # end
46
- #
47
- # If the audit observer needs to watch more than one kind of object, this can be specified with multiple arguments:
48
- #
49
- # class AuditObserver < ActiveRecord::Observer
50
- # observe :account, :balance
51
- #
52
- # def after_update(record)
53
- # AuditTrail.new(record, "UPDATED")
54
- # end
55
- # end
56
- #
57
- # The AuditObserver will now act on both updates to Account and Balance by treating them both as records.
58
- #
59
- # == Available callback methods
60
- #
61
- # The observer can implement callback methods for each of the methods described in the Callbacks module.
62
- #
63
- # == Storing Observers in Rails
64
- #
65
- # If you're using Active Record within Rails, observer classes are usually stored in app/models with the
66
- # naming convention of app/models/audit_observer.rb.
67
- #
68
- # == Configuration
69
- #
70
- # In order to activate an observer, list it in the <tt>config.active_record.observers</tt> configuration
71
- # setting in your <tt>config/application.rb</tt> file.
72
- #
73
- # config.active_record.observers = :comment_observer, :signup_observer
74
- #
75
- # Observers will not be invoked unless you define these in your application configuration.
76
- #
77
- # == Loading
78
- #
79
- # Observers register themselves in the model class they observe, since it is the class that
80
- # notifies them of events when they occur. As a side-effect, when an observer is loaded its
81
- # corresponding model class is loaded.
82
- #
83
- # Up to (and including) Rails 2.0.2 observers were instantiated between plugins and
84
- # application initializers. Now observers are loaded after application initializers,
85
- # so observed models can make use of extensions.
86
- #
87
- # If by any chance you are using observed models in the initialization you can still
88
- # load their observers by calling <tt>ModelObserver.instance</tt> before. Observers are
89
- # singletons and that call instantiates and registers them.
90
- #
91
- class Observer < ActiveModel::Observer
92
-
93
- protected
94
-
95
- def observed_classes
96
- klasses = super
97
- klasses + klasses.map { |klass| klass.descendants }.flatten
98
- end
99
-
100
- def add_observer!(klass)
101
- super
102
- define_callbacks klass
103
- end
104
-
105
- def define_callbacks(klass)
106
- observer = self
107
- observer_name = observer.class.name.underscore.gsub('/', '__')
108
-
109
- ActiveRecord::Callbacks::CALLBACKS.each do |callback|
110
- next unless respond_to?(callback)
111
- callback_meth = :"_notify_#{observer_name}_for_#{callback}"
112
- unless klass.respond_to?(callback_meth)
113
- klass.send(:define_method, callback_meth) do |&block|
114
- observer.update(callback, self, &block)
115
- end
116
- klass.send(callback, callback_meth)
117
- end
118
- end
119
- end
120
- end
121
- end
@@ -1,203 +0,0 @@
1
- require 'active_support/core_ext/array/wrap'
2
- require 'active_support/core_ext/hash/conversions'
3
-
4
- module ActiveRecord #:nodoc:
5
- module Serialization
6
- include ActiveModel::Serializers::Xml
7
-
8
- # Builds an XML document to represent the model. Some configuration is
9
- # available through +options+. However more complicated cases should
10
- # override ActiveRecord::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 ActiveRecord::Base
161
- # subclasses to have complete control about what's generated. The general
162
- # form of doing this is:
163
- #
164
- # class IHaveMyOwnXML < ActiveRecord::Base
165
- # def to_xml(options = {})
166
- # require 'builder'
167
- # options[:indent] ||= 2
168
- # xml = options[:builder] ||= ::Builder::XmlMarkup.new(:indent => options[:indent])
169
- # xml.instruct! unless options[:skip_instruct]
170
- # xml.level_one do
171
- # xml.tag!(:second_level, 'content')
172
- # end
173
- # end
174
- # end
175
- def to_xml(options = {}, &block)
176
- XmlSerializer.new(self, options).serialize(&block)
177
- end
178
- end
179
-
180
- class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc:
181
- def initialize(*args)
182
- super
183
- options[:except] = Array.wrap(options[:except]) | Array.wrap(@serializable.class.inheritance_column)
184
- end
185
-
186
- class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc:
187
- def compute_type
188
- klass = @serializable.class
189
- type = if klass.serialized_attributes.key?(name)
190
- super
191
- elsif klass.columns_hash.key?(name)
192
- klass.columns_hash[name].type
193
- else
194
- NilClass
195
- end
196
-
197
- { :text => :string,
198
- :time => :datetime }[type] || type
199
- end
200
- protected :compute_type
201
- end
202
- end
203
- end