activerecord 2.3.18 → 3.2.22
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +1014 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +222 -0
- data/examples/performance.rb +100 -126
- data/examples/simple.rb +14 -0
- data/lib/active_record/aggregations.rb +93 -99
- data/lib/active_record/associations/alias_tracker.rb +76 -0
- data/lib/active_record/associations/association.rb +247 -0
- data/lib/active_record/associations/association_scope.rb +134 -0
- data/lib/active_record/associations/belongs_to_association.rb +54 -61
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +17 -59
- data/lib/active_record/associations/builder/association.rb +55 -0
- data/lib/active_record/associations/builder/belongs_to.rb +88 -0
- data/lib/active_record/associations/builder/collection_association.rb +75 -0
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +57 -0
- data/lib/active_record/associations/builder/has_many.rb +71 -0
- data/lib/active_record/associations/builder/has_one.rb +62 -0
- data/lib/active_record/associations/builder/singular_association.rb +32 -0
- data/lib/active_record/associations/collection_association.rb +580 -0
- data/lib/active_record/associations/collection_proxy.rb +133 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +39 -119
- data/lib/active_record/associations/has_many_association.rb +60 -79
- data/lib/active_record/associations/has_many_through_association.rb +127 -206
- data/lib/active_record/associations/has_one_association.rb +55 -114
- data/lib/active_record/associations/has_one_through_association.rb +25 -26
- data/lib/active_record/associations/join_dependency/join_association.rb +159 -0
- data/lib/active_record/associations/join_dependency/join_base.rb +24 -0
- data/lib/active_record/associations/join_dependency/join_part.rb +78 -0
- data/lib/active_record/associations/join_dependency.rb +214 -0
- data/lib/active_record/associations/join_helper.rb +55 -0
- data/lib/active_record/associations/preloader/association.rb +125 -0
- data/lib/active_record/associations/preloader/belongs_to.rb +17 -0
- data/lib/active_record/associations/preloader/collection_association.rb +24 -0
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +60 -0
- data/lib/active_record/associations/preloader/has_many.rb +17 -0
- data/lib/active_record/associations/preloader/has_many_through.rb +15 -0
- data/lib/active_record/associations/preloader/has_one.rb +23 -0
- data/lib/active_record/associations/preloader/has_one_through.rb +9 -0
- data/lib/active_record/associations/preloader/singular_association.rb +21 -0
- data/lib/active_record/associations/preloader/through_association.rb +67 -0
- data/lib/active_record/associations/preloader.rb +181 -0
- data/lib/active_record/associations/singular_association.rb +64 -0
- data/lib/active_record/associations/through_association.rb +87 -0
- data/lib/active_record/associations.rb +693 -1337
- data/lib/active_record/attribute_assignment.rb +221 -0
- data/lib/active_record/attribute_methods/before_type_cast.rb +31 -0
- data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +32 -0
- data/lib/active_record/attribute_methods/dirty.rb +111 -0
- data/lib/active_record/attribute_methods/primary_key.rb +114 -0
- data/lib/active_record/attribute_methods/query.rb +39 -0
- data/lib/active_record/attribute_methods/read.rb +136 -0
- data/lib/active_record/attribute_methods/serialization.rb +120 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +65 -0
- data/lib/active_record/attribute_methods/write.rb +70 -0
- data/lib/active_record/attribute_methods.rb +211 -339
- data/lib/active_record/autosave_association.rb +179 -149
- data/lib/active_record/base.rb +401 -2907
- data/lib/active_record/callbacks.rb +91 -176
- data/lib/active_record/coders/yaml_column.rb +41 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +236 -119
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +110 -58
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +12 -11
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +175 -74
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +31 -35
- data/lib/active_record/connection_adapters/abstract/quoting.rb +71 -21
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +81 -311
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +194 -78
- data/lib/active_record/connection_adapters/abstract_adapter.rb +130 -83
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +676 -0
- data/lib/active_record/connection_adapters/column.rb +296 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +280 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +272 -493
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +650 -405
- data/lib/active_record/connection_adapters/schema_cache.rb +69 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +30 -9
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +276 -147
- data/lib/active_record/connection_adapters/statement_pool.rb +40 -0
- data/lib/active_record/counter_cache.rb +123 -0
- data/lib/active_record/dynamic_finder_match.rb +41 -14
- data/lib/active_record/dynamic_matchers.rb +84 -0
- data/lib/active_record/dynamic_scope_match.rb +13 -15
- data/lib/active_record/errors.rb +195 -0
- data/lib/active_record/explain.rb +86 -0
- data/lib/active_record/explain_subscriber.rb +25 -0
- data/lib/active_record/fixtures/file.rb +65 -0
- data/lib/active_record/fixtures.rb +695 -770
- data/lib/active_record/identity_map.rb +162 -0
- data/lib/active_record/inheritance.rb +174 -0
- data/lib/active_record/integration.rb +60 -0
- data/lib/active_record/locale/en.yml +9 -27
- data/lib/active_record/locking/optimistic.rb +76 -73
- data/lib/active_record/locking/pessimistic.rb +32 -10
- data/lib/active_record/log_subscriber.rb +72 -0
- data/lib/active_record/migration/command_recorder.rb +105 -0
- data/lib/active_record/migration.rb +415 -205
- data/lib/active_record/model_schema.rb +368 -0
- data/lib/active_record/nested_attributes.rb +153 -63
- data/lib/active_record/observer.rb +27 -103
- data/lib/active_record/persistence.rb +376 -0
- data/lib/active_record/query_cache.rb +49 -8
- data/lib/active_record/querying.rb +58 -0
- data/lib/active_record/railtie.rb +131 -0
- data/lib/active_record/railties/console_sandbox.rb +6 -0
- data/lib/active_record/railties/controller_runtime.rb +49 -0
- data/lib/active_record/railties/databases.rake +659 -0
- data/lib/active_record/railties/jdbcmysql_error.rb +16 -0
- data/lib/active_record/readonly_attributes.rb +26 -0
- data/lib/active_record/reflection.rb +269 -120
- data/lib/active_record/relation/batches.rb +90 -0
- data/lib/active_record/relation/calculations.rb +372 -0
- data/lib/active_record/relation/delegation.rb +49 -0
- data/lib/active_record/relation/finder_methods.rb +402 -0
- data/lib/active_record/relation/predicate_builder.rb +63 -0
- data/lib/active_record/relation/query_methods.rb +417 -0
- data/lib/active_record/relation/spawn_methods.rb +180 -0
- data/lib/active_record/relation.rb +537 -0
- data/lib/active_record/result.rb +40 -0
- data/lib/active_record/sanitization.rb +194 -0
- data/lib/active_record/schema.rb +9 -6
- data/lib/active_record/schema_dumper.rb +55 -32
- data/lib/active_record/scoping/default.rb +142 -0
- data/lib/active_record/scoping/named.rb +200 -0
- data/lib/active_record/scoping.rb +152 -0
- data/lib/active_record/serialization.rb +8 -91
- data/lib/active_record/serializers/xml_serializer.rb +43 -197
- data/lib/active_record/session_store.rb +129 -103
- data/lib/active_record/store.rb +52 -0
- data/lib/active_record/test_case.rb +30 -23
- data/lib/active_record/timestamp.rb +95 -52
- data/lib/active_record/transactions.rb +212 -66
- data/lib/active_record/translation.rb +22 -0
- data/lib/active_record/validations/associated.rb +43 -0
- data/lib/active_record/validations/uniqueness.rb +180 -0
- data/lib/active_record/validations.rb +43 -1106
- data/lib/active_record/version.rb +5 -4
- data/lib/active_record.rb +121 -48
- data/lib/rails/generators/active_record/migration/migration_generator.rb +25 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb +34 -0
- data/lib/rails/generators/active_record/migration.rb +15 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +47 -0
- data/lib/rails/generators/active_record/model/templates/migration.rb +15 -0
- data/lib/rails/generators/active_record/model/templates/model.rb +12 -0
- data/lib/rails/generators/active_record/model/templates/module.rb +7 -0
- data/lib/rails/generators/active_record/observer/observer_generator.rb +15 -0
- data/lib/rails/generators/active_record/observer/templates/observer.rb +4 -0
- data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +25 -0
- data/lib/rails/generators/active_record/session_migration/templates/migration.rb +12 -0
- data/lib/rails/generators/active_record.rb +25 -0
- metadata +187 -363
- data/CHANGELOG +0 -5904
- data/README +0 -351
- data/RUNNING_UNIT_TESTS +0 -36
- data/Rakefile +0 -268
- data/install.rb +0 -30
- data/lib/active_record/association_preload.rb +0 -406
- data/lib/active_record/associations/association_collection.rb +0 -533
- data/lib/active_record/associations/association_proxy.rb +0 -288
- data/lib/active_record/batches.rb +0 -85
- data/lib/active_record/calculations.rb +0 -321
- data/lib/active_record/dirty.rb +0 -183
- data/lib/active_record/named_scope.rb +0 -197
- data/lib/active_record/serializers/json_serializer.rb +0 -91
- data/lib/activerecord.rb +0 -2
- data/test/assets/example.log +0 -1
- data/test/assets/flowers.jpg +0 -0
- data/test/cases/aaa_create_tables_test.rb +0 -24
- data/test/cases/active_schema_test_mysql.rb +0 -122
- data/test/cases/active_schema_test_postgresql.rb +0 -24
- data/test/cases/adapter_test.rb +0 -144
- data/test/cases/aggregations_test.rb +0 -167
- data/test/cases/ar_schema_test.rb +0 -32
- data/test/cases/associations/belongs_to_associations_test.rb +0 -438
- data/test/cases/associations/callbacks_test.rb +0 -161
- data/test/cases/associations/cascaded_eager_loading_test.rb +0 -131
- data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +0 -36
- data/test/cases/associations/eager_load_nested_include_test.rb +0 -131
- data/test/cases/associations/eager_load_nested_polymorphic_include.rb +0 -19
- data/test/cases/associations/eager_singularization_test.rb +0 -145
- data/test/cases/associations/eager_test.rb +0 -852
- data/test/cases/associations/extension_test.rb +0 -62
- data/test/cases/associations/habtm_join_table_test.rb +0 -56
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +0 -827
- data/test/cases/associations/has_many_associations_test.rb +0 -1273
- data/test/cases/associations/has_many_through_associations_test.rb +0 -360
- data/test/cases/associations/has_one_associations_test.rb +0 -330
- data/test/cases/associations/has_one_through_associations_test.rb +0 -209
- data/test/cases/associations/inner_join_association_test.rb +0 -93
- data/test/cases/associations/inverse_associations_test.rb +0 -566
- data/test/cases/associations/join_model_test.rb +0 -712
- data/test/cases/associations_test.rb +0 -282
- data/test/cases/attribute_methods_test.rb +0 -305
- data/test/cases/autosave_association_test.rb +0 -1218
- data/test/cases/base_test.rb +0 -2166
- data/test/cases/batches_test.rb +0 -81
- data/test/cases/binary_test.rb +0 -30
- data/test/cases/calculations_test.rb +0 -360
- data/test/cases/callbacks_observers_test.rb +0 -38
- data/test/cases/callbacks_test.rb +0 -438
- data/test/cases/class_inheritable_attributes_test.rb +0 -32
- data/test/cases/column_alias_test.rb +0 -17
- data/test/cases/column_definition_test.rb +0 -70
- data/test/cases/connection_pool_test.rb +0 -25
- data/test/cases/connection_test_firebird.rb +0 -8
- data/test/cases/connection_test_mysql.rb +0 -65
- data/test/cases/copy_table_test_sqlite.rb +0 -80
- data/test/cases/counter_cache_test.rb +0 -84
- data/test/cases/database_statements_test.rb +0 -12
- data/test/cases/datatype_test_postgresql.rb +0 -204
- data/test/cases/date_time_test.rb +0 -37
- data/test/cases/default_test_firebird.rb +0 -16
- data/test/cases/defaults_test.rb +0 -111
- data/test/cases/deprecated_finder_test.rb +0 -30
- data/test/cases/dirty_test.rb +0 -316
- data/test/cases/finder_respond_to_test.rb +0 -76
- data/test/cases/finder_test.rb +0 -1098
- data/test/cases/fixtures_test.rb +0 -661
- data/test/cases/helper.rb +0 -68
- data/test/cases/i18n_test.rb +0 -46
- data/test/cases/inheritance_test.rb +0 -262
- data/test/cases/invalid_date_test.rb +0 -24
- data/test/cases/json_serialization_test.rb +0 -219
- data/test/cases/lifecycle_test.rb +0 -193
- data/test/cases/locking_test.rb +0 -350
- data/test/cases/method_scoping_test.rb +0 -704
- data/test/cases/migration_test.rb +0 -1649
- data/test/cases/migration_test_firebird.rb +0 -124
- data/test/cases/mixin_test.rb +0 -96
- data/test/cases/modules_test.rb +0 -109
- data/test/cases/multiple_db_test.rb +0 -85
- data/test/cases/named_scope_test.rb +0 -372
- data/test/cases/nested_attributes_test.rb +0 -840
- data/test/cases/pk_test.rb +0 -119
- data/test/cases/pooled_connections_test.rb +0 -103
- data/test/cases/query_cache_test.rb +0 -129
- data/test/cases/readonly_test.rb +0 -107
- data/test/cases/reflection_test.rb +0 -234
- data/test/cases/reload_models_test.rb +0 -22
- data/test/cases/repair_helper.rb +0 -50
- data/test/cases/reserved_word_test_mysql.rb +0 -176
- data/test/cases/sanitize_test.rb +0 -25
- data/test/cases/schema_authorization_test_postgresql.rb +0 -75
- data/test/cases/schema_dumper_test.rb +0 -211
- data/test/cases/schema_test_postgresql.rb +0 -178
- data/test/cases/serialization_test.rb +0 -47
- data/test/cases/sp_test_mysql.rb +0 -16
- data/test/cases/synonym_test_oracle.rb +0 -17
- data/test/cases/timestamp_test.rb +0 -75
- data/test/cases/transactions_test.rb +0 -543
- data/test/cases/unconnected_test.rb +0 -32
- data/test/cases/validations_i18n_test.rb +0 -925
- data/test/cases/validations_test.rb +0 -1684
- data/test/cases/xml_serialization_test.rb +0 -240
- data/test/cases/yaml_serialization_test.rb +0 -11
- data/test/config.rb +0 -5
- data/test/connections/jdbc_jdbcderby/connection.rb +0 -18
- data/test/connections/jdbc_jdbch2/connection.rb +0 -18
- data/test/connections/jdbc_jdbchsqldb/connection.rb +0 -18
- data/test/connections/jdbc_jdbcmysql/connection.rb +0 -26
- data/test/connections/jdbc_jdbcpostgresql/connection.rb +0 -26
- data/test/connections/jdbc_jdbcsqlite3/connection.rb +0 -25
- data/test/connections/native_db2/connection.rb +0 -25
- data/test/connections/native_firebird/connection.rb +0 -26
- data/test/connections/native_frontbase/connection.rb +0 -27
- data/test/connections/native_mysql/connection.rb +0 -25
- data/test/connections/native_openbase/connection.rb +0 -21
- data/test/connections/native_oracle/connection.rb +0 -27
- data/test/connections/native_postgresql/connection.rb +0 -21
- data/test/connections/native_sqlite/connection.rb +0 -25
- data/test/connections/native_sqlite3/connection.rb +0 -25
- data/test/connections/native_sqlite3/in_memory_connection.rb +0 -18
- data/test/connections/native_sybase/connection.rb +0 -23
- data/test/fixtures/accounts.yml +0 -29
- data/test/fixtures/all/developers.yml +0 -0
- data/test/fixtures/all/people.csv +0 -0
- data/test/fixtures/all/tasks.yml +0 -0
- data/test/fixtures/author_addresses.yml +0 -5
- data/test/fixtures/author_favorites.yml +0 -4
- data/test/fixtures/authors.yml +0 -9
- data/test/fixtures/binaries.yml +0 -132
- data/test/fixtures/books.yml +0 -7
- data/test/fixtures/categories/special_categories.yml +0 -9
- data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +0 -4
- data/test/fixtures/categories.yml +0 -14
- data/test/fixtures/categories_ordered.yml +0 -7
- data/test/fixtures/categories_posts.yml +0 -23
- data/test/fixtures/categorizations.yml +0 -17
- data/test/fixtures/clubs.yml +0 -6
- data/test/fixtures/comments.yml +0 -59
- data/test/fixtures/companies.yml +0 -56
- data/test/fixtures/computers.yml +0 -4
- data/test/fixtures/courses.yml +0 -7
- data/test/fixtures/customers.yml +0 -26
- data/test/fixtures/developers.yml +0 -21
- data/test/fixtures/developers_projects.yml +0 -17
- data/test/fixtures/edges.yml +0 -6
- data/test/fixtures/entrants.yml +0 -14
- data/test/fixtures/faces.yml +0 -11
- data/test/fixtures/fk_test_has_fk.yml +0 -3
- data/test/fixtures/fk_test_has_pk.yml +0 -2
- data/test/fixtures/funny_jokes.yml +0 -10
- data/test/fixtures/interests.yml +0 -33
- data/test/fixtures/items.yml +0 -4
- data/test/fixtures/jobs.yml +0 -7
- data/test/fixtures/legacy_things.yml +0 -3
- data/test/fixtures/mateys.yml +0 -4
- data/test/fixtures/member_types.yml +0 -6
- data/test/fixtures/members.yml +0 -6
- data/test/fixtures/memberships.yml +0 -20
- data/test/fixtures/men.yml +0 -5
- data/test/fixtures/minimalistics.yml +0 -2
- data/test/fixtures/mixed_case_monkeys.yml +0 -6
- data/test/fixtures/mixins.yml +0 -29
- data/test/fixtures/movies.yml +0 -7
- data/test/fixtures/naked/csv/accounts.csv +0 -1
- data/test/fixtures/naked/yml/accounts.yml +0 -1
- data/test/fixtures/naked/yml/companies.yml +0 -1
- data/test/fixtures/naked/yml/courses.yml +0 -1
- data/test/fixtures/organizations.yml +0 -5
- data/test/fixtures/owners.yml +0 -7
- data/test/fixtures/parrots.yml +0 -27
- data/test/fixtures/parrots_pirates.yml +0 -7
- data/test/fixtures/people.yml +0 -15
- data/test/fixtures/pets.yml +0 -14
- data/test/fixtures/pirates.yml +0 -9
- data/test/fixtures/polymorphic_designs.yml +0 -19
- data/test/fixtures/polymorphic_prices.yml +0 -19
- data/test/fixtures/posts.yml +0 -52
- data/test/fixtures/price_estimates.yml +0 -7
- data/test/fixtures/projects.yml +0 -7
- data/test/fixtures/readers.yml +0 -9
- data/test/fixtures/references.yml +0 -17
- data/test/fixtures/reserved_words/distinct.yml +0 -5
- data/test/fixtures/reserved_words/distincts_selects.yml +0 -11
- data/test/fixtures/reserved_words/group.yml +0 -14
- data/test/fixtures/reserved_words/select.yml +0 -8
- data/test/fixtures/reserved_words/values.yml +0 -7
- data/test/fixtures/ships.yml +0 -5
- data/test/fixtures/sponsors.yml +0 -9
- data/test/fixtures/subscribers.yml +0 -7
- data/test/fixtures/subscriptions.yml +0 -12
- data/test/fixtures/taggings.yml +0 -28
- data/test/fixtures/tags.yml +0 -7
- data/test/fixtures/tasks.yml +0 -7
- data/test/fixtures/tees.yml +0 -4
- data/test/fixtures/ties.yml +0 -4
- data/test/fixtures/topics.yml +0 -42
- data/test/fixtures/toys.yml +0 -4
- data/test/fixtures/treasures.yml +0 -10
- data/test/fixtures/vertices.yml +0 -4
- data/test/fixtures/warehouse-things.yml +0 -3
- data/test/fixtures/zines.yml +0 -5
- data/test/migrations/broken/100_migration_that_raises_exception.rb +0 -10
- data/test/migrations/decimal/1_give_me_big_numbers.rb +0 -15
- data/test/migrations/duplicate/1_people_have_last_names.rb +0 -9
- data/test/migrations/duplicate/2_we_need_reminders.rb +0 -12
- data/test/migrations/duplicate/3_foo.rb +0 -7
- data/test/migrations/duplicate/3_innocent_jointable.rb +0 -12
- data/test/migrations/duplicate_names/20080507052938_chunky.rb +0 -7
- data/test/migrations/duplicate_names/20080507053028_chunky.rb +0 -7
- data/test/migrations/interleaved/pass_1/3_innocent_jointable.rb +0 -12
- data/test/migrations/interleaved/pass_2/1_people_have_last_names.rb +0 -9
- data/test/migrations/interleaved/pass_2/3_innocent_jointable.rb +0 -12
- data/test/migrations/interleaved/pass_3/1_people_have_last_names.rb +0 -9
- data/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb +0 -8
- data/test/migrations/interleaved/pass_3/3_innocent_jointable.rb +0 -12
- data/test/migrations/missing/1000_people_have_middle_names.rb +0 -9
- data/test/migrations/missing/1_people_have_last_names.rb +0 -9
- data/test/migrations/missing/3_we_need_reminders.rb +0 -12
- data/test/migrations/missing/4_innocent_jointable.rb +0 -12
- data/test/migrations/valid/1_people_have_last_names.rb +0 -9
- data/test/migrations/valid/2_we_need_reminders.rb +0 -12
- data/test/migrations/valid/3_innocent_jointable.rb +0 -12
- data/test/models/author.rb +0 -151
- data/test/models/auto_id.rb +0 -4
- data/test/models/binary.rb +0 -2
- data/test/models/bird.rb +0 -9
- data/test/models/book.rb +0 -4
- data/test/models/categorization.rb +0 -5
- data/test/models/category.rb +0 -34
- data/test/models/citation.rb +0 -6
- data/test/models/club.rb +0 -13
- data/test/models/column_name.rb +0 -3
- data/test/models/comment.rb +0 -29
- data/test/models/company.rb +0 -173
- data/test/models/company_in_module.rb +0 -78
- data/test/models/computer.rb +0 -3
- data/test/models/contact.rb +0 -16
- data/test/models/contract.rb +0 -5
- data/test/models/course.rb +0 -3
- data/test/models/customer.rb +0 -73
- data/test/models/default.rb +0 -2
- data/test/models/developer.rb +0 -101
- data/test/models/edge.rb +0 -5
- data/test/models/entrant.rb +0 -3
- data/test/models/essay.rb +0 -3
- data/test/models/event.rb +0 -3
- data/test/models/event_author.rb +0 -8
- data/test/models/face.rb +0 -7
- data/test/models/guid.rb +0 -2
- data/test/models/interest.rb +0 -5
- data/test/models/invoice.rb +0 -4
- data/test/models/item.rb +0 -7
- data/test/models/job.rb +0 -5
- data/test/models/joke.rb +0 -3
- data/test/models/keyboard.rb +0 -3
- data/test/models/legacy_thing.rb +0 -3
- data/test/models/line_item.rb +0 -3
- data/test/models/man.rb +0 -9
- data/test/models/matey.rb +0 -4
- data/test/models/member.rb +0 -12
- data/test/models/member_detail.rb +0 -5
- data/test/models/member_type.rb +0 -3
- data/test/models/membership.rb +0 -9
- data/test/models/minimalistic.rb +0 -2
- data/test/models/mixed_case_monkey.rb +0 -3
- data/test/models/movie.rb +0 -5
- data/test/models/order.rb +0 -4
- data/test/models/organization.rb +0 -6
- data/test/models/owner.rb +0 -5
- data/test/models/parrot.rb +0 -22
- data/test/models/person.rb +0 -16
- data/test/models/pet.rb +0 -5
- data/test/models/pirate.rb +0 -80
- data/test/models/polymorphic_design.rb +0 -3
- data/test/models/polymorphic_price.rb +0 -3
- data/test/models/post.rb +0 -102
- data/test/models/price_estimate.rb +0 -3
- data/test/models/project.rb +0 -30
- data/test/models/reader.rb +0 -4
- data/test/models/reference.rb +0 -4
- data/test/models/reply.rb +0 -46
- data/test/models/ship.rb +0 -19
- data/test/models/ship_part.rb +0 -7
- data/test/models/sponsor.rb +0 -4
- data/test/models/subject.rb +0 -4
- data/test/models/subscriber.rb +0 -8
- data/test/models/subscription.rb +0 -4
- data/test/models/tag.rb +0 -7
- data/test/models/tagging.rb +0 -10
- data/test/models/task.rb +0 -3
- data/test/models/tee.rb +0 -4
- data/test/models/tie.rb +0 -4
- data/test/models/topic.rb +0 -80
- data/test/models/toy.rb +0 -6
- data/test/models/treasure.rb +0 -8
- data/test/models/vertex.rb +0 -9
- data/test/models/warehouse_thing.rb +0 -5
- data/test/models/zine.rb +0 -3
- data/test/schema/mysql_specific_schema.rb +0 -31
- data/test/schema/postgresql_specific_schema.rb +0 -114
- data/test/schema/schema.rb +0 -550
- data/test/schema/schema2.rb +0 -6
- data/test/schema/sqlite_specific_schema.rb +0 -25
@@ -0,0 +1,162 @@
|
|
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
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module Inheritance
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
# Determine whether to store the full constant name including namespace when using STI
|
9
|
+
class_attribute :store_full_sti_class
|
10
|
+
self.store_full_sti_class = true
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
# True if this isn't a concrete subclass needing a STI type condition.
|
15
|
+
def descends_from_active_record?
|
16
|
+
if superclass.abstract_class?
|
17
|
+
superclass.descends_from_active_record?
|
18
|
+
else
|
19
|
+
superclass == Base || !columns_hash.include?(inheritance_column)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def finder_needs_type_condition? #:nodoc:
|
24
|
+
# This is like this because benchmarking justifies the strange :false stuff
|
25
|
+
:true == (@finder_needs_type_condition ||= descends_from_active_record? ? :false : :true)
|
26
|
+
end
|
27
|
+
|
28
|
+
def symbolized_base_class
|
29
|
+
@symbolized_base_class ||= base_class.to_s.to_sym
|
30
|
+
end
|
31
|
+
|
32
|
+
def symbolized_sti_name
|
33
|
+
@symbolized_sti_name ||= sti_name.present? ? sti_name.to_sym : symbolized_base_class
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the base AR subclass that this class descends from. If A
|
37
|
+
# extends AR::Base, A.base_class will return A. If B descends from A
|
38
|
+
# through some arbitrarily deep hierarchy, B.base_class will return A.
|
39
|
+
#
|
40
|
+
# If B < A and C < B and if A is an abstract_class then both B.base_class
|
41
|
+
# and C.base_class would return B as the answer since A is an abstract_class.
|
42
|
+
def base_class
|
43
|
+
class_of_active_record_descendant(self)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Set this to true if this is an abstract class (see <tt>abstract_class?</tt>).
|
47
|
+
attr_accessor :abstract_class
|
48
|
+
|
49
|
+
# Returns whether this class is an abstract class or not.
|
50
|
+
def abstract_class?
|
51
|
+
defined?(@abstract_class) && @abstract_class == true
|
52
|
+
end
|
53
|
+
|
54
|
+
def sti_name
|
55
|
+
store_full_sti_class ? name : name.demodulize
|
56
|
+
end
|
57
|
+
|
58
|
+
# Finder methods must instantiate through this method to work with the
|
59
|
+
# single-table inheritance model that makes it possible to create
|
60
|
+
# objects of different types from the same table.
|
61
|
+
def instantiate(record)
|
62
|
+
sti_class = find_sti_class(record[inheritance_column])
|
63
|
+
record_id = sti_class.primary_key && record[sti_class.primary_key]
|
64
|
+
|
65
|
+
if ActiveRecord::IdentityMap.enabled? && record_id
|
66
|
+
instance = use_identity_map(sti_class, record_id, record)
|
67
|
+
else
|
68
|
+
instance = sti_class.allocate.init_with('attributes' => record)
|
69
|
+
end
|
70
|
+
|
71
|
+
instance
|
72
|
+
end
|
73
|
+
|
74
|
+
protected
|
75
|
+
|
76
|
+
# Returns the class descending directly from ActiveRecord::Base or an
|
77
|
+
# abstract class, if any, in the inheritance hierarchy.
|
78
|
+
def class_of_active_record_descendant(klass)
|
79
|
+
if klass == Base || klass.superclass == Base || klass.superclass.abstract_class?
|
80
|
+
klass
|
81
|
+
elsif klass.superclass.nil?
|
82
|
+
raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord"
|
83
|
+
else
|
84
|
+
class_of_active_record_descendant(klass.superclass)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns the class type of the record using the current module as a prefix. So descendants of
|
89
|
+
# MyApp::Business::Account would appear as MyApp::Business::AccountSubclass.
|
90
|
+
def compute_type(type_name)
|
91
|
+
if type_name.match(/^::/)
|
92
|
+
# If the type is prefixed with a scope operator then we assume that
|
93
|
+
# the type_name is an absolute reference.
|
94
|
+
ActiveSupport::Dependencies.constantize(type_name)
|
95
|
+
else
|
96
|
+
# Build a list of candidates to search for
|
97
|
+
candidates = []
|
98
|
+
name.scan(/::|$/) { candidates.unshift "#{$`}::#{type_name}" }
|
99
|
+
candidates << type_name
|
100
|
+
|
101
|
+
candidates.each do |candidate|
|
102
|
+
begin
|
103
|
+
constant = ActiveSupport::Dependencies.constantize(candidate)
|
104
|
+
return constant if candidate == constant.to_s
|
105
|
+
rescue NameError => e
|
106
|
+
# We don't want to swallow NoMethodError < NameError errors
|
107
|
+
raise e unless e.instance_of?(NameError)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
raise NameError, "uninitialized constant #{candidates.first}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def use_identity_map(sti_class, record_id, record)
|
118
|
+
if (column = sti_class.columns_hash[sti_class.primary_key]) && column.number?
|
119
|
+
record_id = record_id.to_i
|
120
|
+
end
|
121
|
+
|
122
|
+
if instance = IdentityMap.get(sti_class, record_id)
|
123
|
+
instance.reinit_with('attributes' => record)
|
124
|
+
else
|
125
|
+
instance = sti_class.allocate.init_with('attributes' => record)
|
126
|
+
IdentityMap.add(instance)
|
127
|
+
end
|
128
|
+
|
129
|
+
instance
|
130
|
+
end
|
131
|
+
|
132
|
+
def find_sti_class(type_name)
|
133
|
+
if type_name.blank? || !columns_hash.include?(inheritance_column)
|
134
|
+
self
|
135
|
+
else
|
136
|
+
begin
|
137
|
+
if store_full_sti_class
|
138
|
+
ActiveSupport::Dependencies.constantize(type_name)
|
139
|
+
else
|
140
|
+
compute_type(type_name)
|
141
|
+
end
|
142
|
+
rescue NameError
|
143
|
+
raise SubclassNotFound,
|
144
|
+
"The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " +
|
145
|
+
"This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " +
|
146
|
+
"Please rename this column if you didn't intend it to be used for storing the inheritance class " +
|
147
|
+
"or overwrite #{name}.inheritance_column to use another column for that information."
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def type_condition(table = arel_table)
|
153
|
+
sti_column = table[inheritance_column.to_sym]
|
154
|
+
sti_names = ([self] + descendants).map { |model| model.sti_name }
|
155
|
+
|
156
|
+
sti_column.in(sti_names)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
# Sets the attribute used for single table inheritance to this class name if this is not the
|
163
|
+
# ActiveRecord::Base descendant.
|
164
|
+
# Considering the hierarchy Reply < Message < ActiveRecord::Base, this makes it possible to
|
165
|
+
# do Reply.new without having to set <tt>Reply[Reply.inheritance_column] = "Reply"</tt> yourself.
|
166
|
+
# No such attribute would be set for objects of the Message class in that example.
|
167
|
+
def ensure_proper_type
|
168
|
+
klass = self.class
|
169
|
+
if klass.finder_needs_type_condition?
|
170
|
+
write_attribute(klass.inheritance_column, klass.sti_name)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Integration
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
##
|
7
|
+
# :singleton-method:
|
8
|
+
# Indicates the format used to generate the timestamp format in the cache key.
|
9
|
+
# This is +:number+, by default.
|
10
|
+
class_attribute :cache_timestamp_format, :instance_writer => false
|
11
|
+
self.cache_timestamp_format = :number
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns a String, which Action Pack uses for constructing an URL to this
|
15
|
+
# object. The default implementation returns this record's id as a String,
|
16
|
+
# or nil if this record's unsaved.
|
17
|
+
#
|
18
|
+
# For example, suppose that you have a User model, and that you have a
|
19
|
+
# <tt>resources :users</tt> route. Normally, +user_path+ will
|
20
|
+
# construct a path with the user object's 'id' in it:
|
21
|
+
#
|
22
|
+
# user = User.find_by_name('Phusion')
|
23
|
+
# user_path(user) # => "/users/1"
|
24
|
+
#
|
25
|
+
# You can override +to_param+ in your model to make +user_path+ construct
|
26
|
+
# a path using the user's name instead of the user's id:
|
27
|
+
#
|
28
|
+
# class User < ActiveRecord::Base
|
29
|
+
# def to_param # overridden
|
30
|
+
# name
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# user = User.find_by_name('Phusion')
|
35
|
+
# user_path(user) # => "/users/Phusion"
|
36
|
+
def to_param
|
37
|
+
# We can't use alias_method here, because method 'id' optimizes itself on the fly.
|
38
|
+
id && id.to_s # Be sure to stringify the id for routes
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns a cache key that can be used to identify this record.
|
42
|
+
#
|
43
|
+
# ==== Examples
|
44
|
+
#
|
45
|
+
# Product.new.cache_key # => "products/new"
|
46
|
+
# Product.find(5).cache_key # => "products/5" (updated_at not available)
|
47
|
+
# Person.find(5).cache_key # => "people/5-20071224150000" (updated_at available)
|
48
|
+
def cache_key
|
49
|
+
case
|
50
|
+
when new_record?
|
51
|
+
"#{self.class.model_name.cache_key}/new"
|
52
|
+
when timestamp = self[:updated_at]
|
53
|
+
timestamp = timestamp.utc.to_s(cache_timestamp_format)
|
54
|
+
"#{self.class.model_name.cache_key}/#{id}-#{timestamp}"
|
55
|
+
else
|
56
|
+
"#{self.class.model_name.cache_key}/#{id}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -1,34 +1,17 @@
|
|
1
1
|
en:
|
2
|
+
# Attributes names common to most models
|
3
|
+
#attributes:
|
4
|
+
#created_at: "Created at"
|
5
|
+
#updated_at: "Updated at"
|
6
|
+
|
7
|
+
# Active Record models configuration
|
2
8
|
activerecord:
|
3
9
|
errors:
|
4
|
-
# The values :model, :attribute and :value are always available for interpolation
|
5
|
-
# The value :count is available when applicable. Can be used for pluralization.
|
6
10
|
messages:
|
7
|
-
inclusion: "is not included in the list"
|
8
|
-
exclusion: "is reserved"
|
9
|
-
invalid: "is invalid"
|
10
|
-
confirmation: "doesn't match confirmation"
|
11
|
-
accepted: "must be accepted"
|
12
|
-
empty: "can't be empty"
|
13
|
-
blank: "can't be blank"
|
14
|
-
too_long: "is too long (maximum is %{count} characters)"
|
15
|
-
too_short: "is too short (minimum is %{count} characters)"
|
16
|
-
wrong_length: "is the wrong length (should be %{count} characters)"
|
17
11
|
taken: "has already been taken"
|
18
|
-
not_a_number: "is not a number"
|
19
|
-
greater_than: "must be greater than %{count}"
|
20
|
-
greater_than_or_equal_to: "must be greater than or equal to %{count}"
|
21
|
-
equal_to: "must be equal to %{count}"
|
22
|
-
less_than: "must be less than %{count}"
|
23
|
-
less_than_or_equal_to: "must be less than or equal to %{count}"
|
24
|
-
odd: "must be odd"
|
25
|
-
even: "must be even"
|
26
12
|
record_invalid: "Validation failed: %{errors}"
|
27
13
|
# Append your own errors here or at the model/attributes scope.
|
28
14
|
|
29
|
-
full_messages:
|
30
|
-
format: "%{attribute} %{message}"
|
31
|
-
|
32
15
|
# You can define own errors for models or model attributes.
|
33
16
|
# The values :model, :attribute and :value are always available for interpolation.
|
34
17
|
#
|
@@ -39,20 +22,19 @@ en:
|
|
39
22
|
# attributes:
|
40
23
|
# login:
|
41
24
|
# blank: "This is a custom blank message for User login"
|
42
|
-
# Will define custom blank validation message for User model and
|
25
|
+
# Will define custom blank validation message for User model and
|
43
26
|
# custom blank validation message for login attribute of User model.
|
44
27
|
#models:
|
45
|
-
|
28
|
+
|
46
29
|
# Translate model names. Used in Model.human_name().
|
47
30
|
#models:
|
48
31
|
# For example,
|
49
32
|
# user: "Dude"
|
50
33
|
# will translate User model name to "Dude"
|
51
|
-
|
34
|
+
|
52
35
|
# Translate model attribute names. Used in Model.human_attribute_name(attribute).
|
53
36
|
#attributes:
|
54
37
|
# For example,
|
55
38
|
# user:
|
56
39
|
# login: "Handle"
|
57
40
|
# will translate User attribute "login" as "Handle"
|
58
|
-
|