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
@@ -1,1218 +0,0 @@
|
|
1
|
-
require 'cases/helper'
|
2
|
-
require 'models/bird'
|
3
|
-
require 'models/company'
|
4
|
-
require 'models/customer'
|
5
|
-
require 'models/developer'
|
6
|
-
require 'models/invoice'
|
7
|
-
require 'models/line_item'
|
8
|
-
require 'models/order'
|
9
|
-
require 'models/parrot'
|
10
|
-
require 'models/person'
|
11
|
-
require 'models/pirate'
|
12
|
-
require 'models/post'
|
13
|
-
require 'models/reader'
|
14
|
-
require 'models/ship'
|
15
|
-
require 'models/ship_part'
|
16
|
-
require 'models/treasure'
|
17
|
-
|
18
|
-
class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase
|
19
|
-
def test_autosave_should_be_a_valid_option_for_has_one
|
20
|
-
assert base.valid_keys_for_has_one_association.include?(:autosave)
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_autosave_should_be_a_valid_option_for_belongs_to
|
24
|
-
assert base.valid_keys_for_belongs_to_association.include?(:autosave)
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_autosave_should_be_a_valid_option_for_has_many
|
28
|
-
assert base.valid_keys_for_has_many_association.include?(:autosave)
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_autosave_should_be_a_valid_option_for_has_and_belongs_to_many
|
32
|
-
assert base.valid_keys_for_has_and_belongs_to_many_association.include?(:autosave)
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_should_not_add_the_same_callbacks_multiple_times_for_has_one
|
36
|
-
assert_no_difference_when_adding_callbacks_twice_for Pirate, :ship
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_should_not_add_the_same_callbacks_multiple_times_for_belongs_to
|
40
|
-
assert_no_difference_when_adding_callbacks_twice_for Ship, :pirate
|
41
|
-
end
|
42
|
-
|
43
|
-
def test_should_not_add_the_same_callbacks_multiple_times_for_has_many
|
44
|
-
assert_no_difference_when_adding_callbacks_twice_for Pirate, :birds
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_should_not_add_the_same_callbacks_multiple_times_for_has_and_belongs_to_many
|
48
|
-
assert_no_difference_when_adding_callbacks_twice_for Pirate, :parrots
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def base
|
54
|
-
ActiveRecord::Base
|
55
|
-
end
|
56
|
-
|
57
|
-
def assert_no_difference_when_adding_callbacks_twice_for(model, association_name)
|
58
|
-
reflection = model.reflect_on_association(association_name)
|
59
|
-
assert_no_difference "callbacks_for_model(#{model.name}).length" do
|
60
|
-
model.send(:add_autosave_association_callbacks, reflection)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def callbacks_for_model(model)
|
65
|
-
model.instance_variables.grep(/_callbacks$/).map do |ivar|
|
66
|
-
model.instance_variable_get(ivar)
|
67
|
-
end.flatten
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
|
72
|
-
def test_should_save_parent_but_not_invalid_child
|
73
|
-
firm = Firm.new(:name => 'GlobalMegaCorp')
|
74
|
-
assert firm.valid?
|
75
|
-
|
76
|
-
firm.build_account_using_primary_key
|
77
|
-
assert !firm.build_account_using_primary_key.valid?
|
78
|
-
|
79
|
-
assert firm.save
|
80
|
-
assert firm.account_using_primary_key.new_record?
|
81
|
-
end
|
82
|
-
|
83
|
-
def test_save_fails_for_invalid_has_one
|
84
|
-
firm = Firm.find(:first)
|
85
|
-
assert firm.valid?
|
86
|
-
|
87
|
-
firm.account = Account.new
|
88
|
-
|
89
|
-
assert !firm.account.valid?
|
90
|
-
assert !firm.valid?
|
91
|
-
assert !firm.save
|
92
|
-
assert_equal "is invalid", firm.errors.on("account")
|
93
|
-
end
|
94
|
-
|
95
|
-
def test_save_succeeds_for_invalid_has_one_with_validate_false
|
96
|
-
firm = Firm.find(:first)
|
97
|
-
assert firm.valid?
|
98
|
-
|
99
|
-
firm.unvalidated_account = Account.new
|
100
|
-
|
101
|
-
assert !firm.unvalidated_account.valid?
|
102
|
-
assert firm.valid?
|
103
|
-
assert firm.save
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_build_before_child_saved
|
107
|
-
firm = Firm.find(1)
|
108
|
-
|
109
|
-
account = firm.account.build("credit_limit" => 1000)
|
110
|
-
assert_equal account, firm.account
|
111
|
-
assert account.new_record?
|
112
|
-
assert firm.save
|
113
|
-
assert_equal account, firm.account
|
114
|
-
assert !account.new_record?
|
115
|
-
end
|
116
|
-
|
117
|
-
def test_build_before_either_saved
|
118
|
-
firm = Firm.new("name" => "GlobalMegaCorp")
|
119
|
-
|
120
|
-
firm.account = account = Account.new("credit_limit" => 1000)
|
121
|
-
assert_equal account, firm.account
|
122
|
-
assert account.new_record?
|
123
|
-
assert firm.save
|
124
|
-
assert_equal account, firm.account
|
125
|
-
assert !account.new_record?
|
126
|
-
end
|
127
|
-
|
128
|
-
def test_assignment_before_parent_saved
|
129
|
-
firm = Firm.new("name" => "GlobalMegaCorp")
|
130
|
-
firm.account = a = Account.find(1)
|
131
|
-
assert firm.new_record?
|
132
|
-
assert_equal a, firm.account
|
133
|
-
assert firm.save
|
134
|
-
assert_equal a, firm.account
|
135
|
-
assert_equal a, firm.account(true)
|
136
|
-
end
|
137
|
-
|
138
|
-
def test_assignment_before_either_saved
|
139
|
-
firm = Firm.new("name" => "GlobalMegaCorp")
|
140
|
-
firm.account = a = Account.new("credit_limit" => 1000)
|
141
|
-
assert firm.new_record?
|
142
|
-
assert a.new_record?
|
143
|
-
assert_equal a, firm.account
|
144
|
-
assert firm.save
|
145
|
-
assert !firm.new_record?
|
146
|
-
assert !a.new_record?
|
147
|
-
assert_equal a, firm.account
|
148
|
-
assert_equal a, firm.account(true)
|
149
|
-
end
|
150
|
-
|
151
|
-
def test_not_resaved_when_unchanged
|
152
|
-
firm = Firm.find(:first, :include => :account)
|
153
|
-
firm.name += '-changed'
|
154
|
-
assert_queries(1) { firm.save! }
|
155
|
-
|
156
|
-
firm = Firm.find(:first)
|
157
|
-
firm.account = Account.find(:first)
|
158
|
-
assert_queries(Firm.partial_updates? ? 0 : 1) { firm.save! }
|
159
|
-
|
160
|
-
firm = Firm.find(:first).clone
|
161
|
-
firm.account = Account.find(:first)
|
162
|
-
assert_queries(2) { firm.save! }
|
163
|
-
|
164
|
-
firm = Firm.find(:first).clone
|
165
|
-
firm.account = Account.find(:first).clone
|
166
|
-
assert_queries(2) { firm.save! }
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase
|
171
|
-
def test_should_save_parent_but_not_invalid_child
|
172
|
-
client = Client.new(:name => 'Joe (the Plumber)')
|
173
|
-
assert client.valid?
|
174
|
-
|
175
|
-
client.build_firm
|
176
|
-
assert !client.firm.valid?
|
177
|
-
|
178
|
-
assert client.save
|
179
|
-
assert client.firm.new_record?
|
180
|
-
end
|
181
|
-
|
182
|
-
def test_save_fails_for_invalid_belongs_to
|
183
|
-
assert log = AuditLog.create(:developer_id => 0, :message => "")
|
184
|
-
|
185
|
-
log.developer = Developer.new
|
186
|
-
assert !log.developer.valid?
|
187
|
-
assert !log.valid?
|
188
|
-
assert !log.save
|
189
|
-
assert_equal "is invalid", log.errors.on("developer")
|
190
|
-
end
|
191
|
-
|
192
|
-
def test_save_succeeds_for_invalid_belongs_to_with_validate_false
|
193
|
-
assert log = AuditLog.create(:developer_id => 0, :message=> "")
|
194
|
-
|
195
|
-
log.unvalidated_developer = Developer.new
|
196
|
-
assert !log.unvalidated_developer.valid?
|
197
|
-
assert log.valid?
|
198
|
-
assert log.save
|
199
|
-
end
|
200
|
-
|
201
|
-
def test_assignment_before_parent_saved
|
202
|
-
client = Client.find(:first)
|
203
|
-
apple = Firm.new("name" => "Apple")
|
204
|
-
client.firm = apple
|
205
|
-
assert_equal apple, client.firm
|
206
|
-
assert apple.new_record?
|
207
|
-
assert client.save
|
208
|
-
assert apple.save
|
209
|
-
assert !apple.new_record?
|
210
|
-
assert_equal apple, client.firm
|
211
|
-
assert_equal apple, client.firm(true)
|
212
|
-
end
|
213
|
-
|
214
|
-
def test_assignment_before_either_saved
|
215
|
-
final_cut = Client.new("name" => "Final Cut")
|
216
|
-
apple = Firm.new("name" => "Apple")
|
217
|
-
final_cut.firm = apple
|
218
|
-
assert final_cut.new_record?
|
219
|
-
assert apple.new_record?
|
220
|
-
assert final_cut.save
|
221
|
-
assert !final_cut.new_record?
|
222
|
-
assert !apple.new_record?
|
223
|
-
assert_equal apple, final_cut.firm
|
224
|
-
assert_equal apple, final_cut.firm(true)
|
225
|
-
end
|
226
|
-
|
227
|
-
def test_store_two_association_with_one_save
|
228
|
-
num_orders = Order.count
|
229
|
-
num_customers = Customer.count
|
230
|
-
order = Order.new
|
231
|
-
|
232
|
-
customer1 = order.billing = Customer.new
|
233
|
-
customer2 = order.shipping = Customer.new
|
234
|
-
assert order.save
|
235
|
-
assert_equal customer1, order.billing
|
236
|
-
assert_equal customer2, order.shipping
|
237
|
-
|
238
|
-
order.reload
|
239
|
-
|
240
|
-
assert_equal customer1, order.billing
|
241
|
-
assert_equal customer2, order.shipping
|
242
|
-
|
243
|
-
assert_equal num_orders +1, Order.count
|
244
|
-
assert_equal num_customers +2, Customer.count
|
245
|
-
end
|
246
|
-
|
247
|
-
def test_store_association_in_two_relations_with_one_save
|
248
|
-
num_orders = Order.count
|
249
|
-
num_customers = Customer.count
|
250
|
-
order = Order.new
|
251
|
-
|
252
|
-
customer = order.billing = order.shipping = Customer.new
|
253
|
-
assert order.save
|
254
|
-
assert_equal customer, order.billing
|
255
|
-
assert_equal customer, order.shipping
|
256
|
-
|
257
|
-
order.reload
|
258
|
-
|
259
|
-
assert_equal customer, order.billing
|
260
|
-
assert_equal customer, order.shipping
|
261
|
-
|
262
|
-
assert_equal num_orders +1, Order.count
|
263
|
-
assert_equal num_customers +1, Customer.count
|
264
|
-
end
|
265
|
-
|
266
|
-
def test_store_association_in_two_relations_with_one_save_in_existing_object
|
267
|
-
num_orders = Order.count
|
268
|
-
num_customers = Customer.count
|
269
|
-
order = Order.create
|
270
|
-
|
271
|
-
customer = order.billing = order.shipping = Customer.new
|
272
|
-
assert order.save
|
273
|
-
assert_equal customer, order.billing
|
274
|
-
assert_equal customer, order.shipping
|
275
|
-
|
276
|
-
order.reload
|
277
|
-
|
278
|
-
assert_equal customer, order.billing
|
279
|
-
assert_equal customer, order.shipping
|
280
|
-
|
281
|
-
assert_equal num_orders +1, Order.count
|
282
|
-
assert_equal num_customers +1, Customer.count
|
283
|
-
end
|
284
|
-
|
285
|
-
def test_store_association_in_two_relations_with_one_save_in_existing_object_with_values
|
286
|
-
num_orders = Order.count
|
287
|
-
num_customers = Customer.count
|
288
|
-
order = Order.create
|
289
|
-
|
290
|
-
customer = order.billing = order.shipping = Customer.new
|
291
|
-
assert order.save
|
292
|
-
assert_equal customer, order.billing
|
293
|
-
assert_equal customer, order.shipping
|
294
|
-
|
295
|
-
order.reload
|
296
|
-
|
297
|
-
customer = order.billing = order.shipping = Customer.new
|
298
|
-
|
299
|
-
assert order.save
|
300
|
-
order.reload
|
301
|
-
|
302
|
-
assert_equal customer, order.billing
|
303
|
-
assert_equal customer, order.shipping
|
304
|
-
|
305
|
-
assert_equal num_orders +1, Order.count
|
306
|
-
assert_equal num_customers +2, Customer.count
|
307
|
-
end
|
308
|
-
end
|
309
|
-
|
310
|
-
class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase
|
311
|
-
fixtures :companies, :people
|
312
|
-
|
313
|
-
def test_invalid_adding
|
314
|
-
firm = Firm.find(1)
|
315
|
-
assert !(firm.clients_of_firm << c = Client.new)
|
316
|
-
assert c.new_record?
|
317
|
-
assert !firm.valid?
|
318
|
-
assert !firm.save
|
319
|
-
assert c.new_record?
|
320
|
-
end
|
321
|
-
|
322
|
-
def test_invalid_adding_before_save
|
323
|
-
no_of_firms = Firm.count
|
324
|
-
no_of_clients = Client.count
|
325
|
-
new_firm = Firm.new("name" => "A New Firm, Inc")
|
326
|
-
new_firm.clients_of_firm.concat([c = Client.new, Client.new("name" => "Apple")])
|
327
|
-
assert c.new_record?
|
328
|
-
assert !c.valid?
|
329
|
-
assert !new_firm.valid?
|
330
|
-
assert !new_firm.save
|
331
|
-
assert c.new_record?
|
332
|
-
assert new_firm.new_record?
|
333
|
-
end
|
334
|
-
|
335
|
-
def test_invalid_adding_with_validate_false
|
336
|
-
firm = Firm.find(:first)
|
337
|
-
client = Client.new
|
338
|
-
firm.unvalidated_clients_of_firm << client
|
339
|
-
|
340
|
-
assert firm.valid?
|
341
|
-
assert !client.valid?
|
342
|
-
assert firm.save
|
343
|
-
assert client.new_record?
|
344
|
-
end
|
345
|
-
|
346
|
-
def test_valid_adding_with_validate_false
|
347
|
-
no_of_clients = Client.count
|
348
|
-
|
349
|
-
firm = Firm.find(:first)
|
350
|
-
client = Client.new("name" => "Apple")
|
351
|
-
|
352
|
-
assert firm.valid?
|
353
|
-
assert client.valid?
|
354
|
-
assert client.new_record?
|
355
|
-
|
356
|
-
firm.unvalidated_clients_of_firm << client
|
357
|
-
|
358
|
-
assert firm.save
|
359
|
-
assert !client.new_record?
|
360
|
-
assert_equal no_of_clients+1, Client.count
|
361
|
-
end
|
362
|
-
|
363
|
-
def test_invalid_build
|
364
|
-
new_client = companies(:first_firm).clients_of_firm.build
|
365
|
-
assert new_client.new_record?
|
366
|
-
assert !new_client.valid?
|
367
|
-
assert_equal new_client, companies(:first_firm).clients_of_firm.last
|
368
|
-
assert !companies(:first_firm).save
|
369
|
-
assert new_client.new_record?
|
370
|
-
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
|
371
|
-
end
|
372
|
-
|
373
|
-
def test_adding_before_save
|
374
|
-
no_of_firms = Firm.count
|
375
|
-
no_of_clients = Client.count
|
376
|
-
|
377
|
-
new_firm = Firm.new("name" => "A New Firm, Inc")
|
378
|
-
c = Client.new("name" => "Apple")
|
379
|
-
|
380
|
-
new_firm.clients_of_firm.push Client.new("name" => "Natural Company")
|
381
|
-
assert_equal 1, new_firm.clients_of_firm.size
|
382
|
-
new_firm.clients_of_firm << c
|
383
|
-
assert_equal 2, new_firm.clients_of_firm.size
|
384
|
-
|
385
|
-
assert_equal no_of_firms, Firm.count # Firm was not saved to database.
|
386
|
-
assert_equal no_of_clients, Client.count # Clients were not saved to database.
|
387
|
-
assert new_firm.save
|
388
|
-
assert !new_firm.new_record?
|
389
|
-
assert !c.new_record?
|
390
|
-
assert_equal new_firm, c.firm
|
391
|
-
assert_equal no_of_firms+1, Firm.count # Firm was saved to database.
|
392
|
-
assert_equal no_of_clients+2, Client.count # Clients were saved to database.
|
393
|
-
|
394
|
-
assert_equal 2, new_firm.clients_of_firm.size
|
395
|
-
assert_equal 2, new_firm.clients_of_firm(true).size
|
396
|
-
end
|
397
|
-
|
398
|
-
def test_assign_ids
|
399
|
-
firm = Firm.new("name" => "Apple")
|
400
|
-
firm.client_ids = [companies(:first_client).id, companies(:second_client).id]
|
401
|
-
firm.save
|
402
|
-
firm.reload
|
403
|
-
assert_equal 2, firm.clients.length
|
404
|
-
assert firm.clients.include?(companies(:second_client))
|
405
|
-
end
|
406
|
-
|
407
|
-
def test_assign_ids_for_through_a_belongs_to
|
408
|
-
post = Post.new(:title => "Assigning IDs works!", :body => "You heared it here first, folks!")
|
409
|
-
post.person_ids = [people(:david).id, people(:michael).id]
|
410
|
-
post.save
|
411
|
-
post.reload
|
412
|
-
assert_equal 2, post.people.length
|
413
|
-
assert post.people.include?(people(:david))
|
414
|
-
end
|
415
|
-
|
416
|
-
def test_build_before_save
|
417
|
-
company = companies(:first_firm)
|
418
|
-
new_client = assert_no_queries { company.clients_of_firm.build("name" => "Another Client") }
|
419
|
-
assert !company.clients_of_firm.loaded?
|
420
|
-
|
421
|
-
company.name += '-changed'
|
422
|
-
assert_queries(2) { assert company.save }
|
423
|
-
assert !new_client.new_record?
|
424
|
-
assert_equal 2, company.clients_of_firm(true).size
|
425
|
-
end
|
426
|
-
|
427
|
-
def test_build_many_before_save
|
428
|
-
company = companies(:first_firm)
|
429
|
-
new_clients = assert_no_queries { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) }
|
430
|
-
|
431
|
-
company.name += '-changed'
|
432
|
-
assert_queries(3) { assert company.save }
|
433
|
-
assert_equal 3, company.clients_of_firm(true).size
|
434
|
-
end
|
435
|
-
|
436
|
-
def test_build_via_block_before_save
|
437
|
-
company = companies(:first_firm)
|
438
|
-
new_client = assert_no_queries { company.clients_of_firm.build {|client| client.name = "Another Client" } }
|
439
|
-
assert !company.clients_of_firm.loaded?
|
440
|
-
|
441
|
-
company.name += '-changed'
|
442
|
-
assert_queries(2) { assert company.save }
|
443
|
-
assert !new_client.new_record?
|
444
|
-
assert_equal 2, company.clients_of_firm(true).size
|
445
|
-
end
|
446
|
-
|
447
|
-
def test_build_many_via_block_before_save
|
448
|
-
company = companies(:first_firm)
|
449
|
-
new_clients = assert_no_queries do
|
450
|
-
company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) do |client|
|
451
|
-
client.name = "changed"
|
452
|
-
end
|
453
|
-
end
|
454
|
-
|
455
|
-
company.name += '-changed'
|
456
|
-
assert_queries(3) { assert company.save }
|
457
|
-
assert_equal 3, company.clients_of_firm(true).size
|
458
|
-
end
|
459
|
-
|
460
|
-
def test_replace_on_new_object
|
461
|
-
firm = Firm.new("name" => "New Firm")
|
462
|
-
firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
|
463
|
-
assert firm.save
|
464
|
-
firm.reload
|
465
|
-
assert_equal 2, firm.clients.length
|
466
|
-
assert firm.clients.include?(Client.find_by_name("New Client"))
|
467
|
-
end
|
468
|
-
end
|
469
|
-
|
470
|
-
class TestDefaultAutosaveAssociationOnNewRecord < ActiveRecord::TestCase
|
471
|
-
def test_autosave_new_record_on_belongs_to_can_be_disabled_per_relationship
|
472
|
-
new_account = Account.new("credit_limit" => 1000)
|
473
|
-
new_firm = Firm.new("name" => "some firm")
|
474
|
-
|
475
|
-
assert new_firm.new_record?
|
476
|
-
new_account.firm = new_firm
|
477
|
-
new_account.save!
|
478
|
-
|
479
|
-
assert !new_firm.new_record?
|
480
|
-
|
481
|
-
new_account = Account.new("credit_limit" => 1000)
|
482
|
-
new_autosaved_firm = Firm.new("name" => "some firm")
|
483
|
-
|
484
|
-
assert new_autosaved_firm.new_record?
|
485
|
-
new_account.unautosaved_firm = new_autosaved_firm
|
486
|
-
new_account.save!
|
487
|
-
|
488
|
-
assert new_autosaved_firm.new_record?
|
489
|
-
end
|
490
|
-
|
491
|
-
def test_autosave_new_record_on_has_one_can_be_disabled_per_relationship
|
492
|
-
firm = Firm.new("name" => "some firm")
|
493
|
-
account = Account.new("credit_limit" => 1000)
|
494
|
-
|
495
|
-
assert account.new_record?
|
496
|
-
firm.account = account
|
497
|
-
firm.save!
|
498
|
-
|
499
|
-
assert !account.new_record?
|
500
|
-
|
501
|
-
firm = Firm.new("name" => "some firm")
|
502
|
-
account = Account.new("credit_limit" => 1000)
|
503
|
-
|
504
|
-
firm.unautosaved_account = account
|
505
|
-
|
506
|
-
assert account.new_record?
|
507
|
-
firm.unautosaved_account = account
|
508
|
-
firm.save!
|
509
|
-
|
510
|
-
assert account.new_record?
|
511
|
-
end
|
512
|
-
|
513
|
-
def test_autosave_new_record_on_has_many_can_be_disabled_per_relationship
|
514
|
-
firm = Firm.new("name" => "some firm")
|
515
|
-
account = Account.new("credit_limit" => 1000)
|
516
|
-
|
517
|
-
assert account.new_record?
|
518
|
-
firm.accounts << account
|
519
|
-
|
520
|
-
firm.save!
|
521
|
-
assert !account.new_record?
|
522
|
-
|
523
|
-
firm = Firm.new("name" => "some firm")
|
524
|
-
account = Account.new("credit_limit" => 1000)
|
525
|
-
|
526
|
-
assert account.new_record?
|
527
|
-
firm.unautosaved_accounts << account
|
528
|
-
|
529
|
-
firm.save!
|
530
|
-
assert account.new_record?
|
531
|
-
end
|
532
|
-
end
|
533
|
-
|
534
|
-
class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
|
535
|
-
self.use_transactional_fixtures = false
|
536
|
-
|
537
|
-
def setup
|
538
|
-
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
539
|
-
@ship = @pirate.create_ship(:name => 'Nights Dirty Lightning')
|
540
|
-
end
|
541
|
-
|
542
|
-
# reload
|
543
|
-
def test_a_marked_for_destruction_record_should_not_be_be_marked_after_reload
|
544
|
-
@pirate.mark_for_destruction
|
545
|
-
@pirate.ship.mark_for_destruction
|
546
|
-
|
547
|
-
assert !@pirate.reload.marked_for_destruction?
|
548
|
-
assert !@pirate.ship.marked_for_destruction?
|
549
|
-
end
|
550
|
-
|
551
|
-
# has_one
|
552
|
-
def test_should_destroy_a_child_association_as_part_of_the_save_transaction_if_it_was_marked_for_destroyal
|
553
|
-
assert !@pirate.ship.marked_for_destruction?
|
554
|
-
|
555
|
-
@pirate.ship.mark_for_destruction
|
556
|
-
id = @pirate.ship.id
|
557
|
-
|
558
|
-
assert @pirate.ship.marked_for_destruction?
|
559
|
-
assert Ship.find_by_id(id)
|
560
|
-
|
561
|
-
@pirate.save
|
562
|
-
assert_nil @pirate.reload.ship
|
563
|
-
assert_nil Ship.find_by_id(id)
|
564
|
-
end
|
565
|
-
|
566
|
-
def test_should_skip_validation_on_a_child_association_if_marked_for_destruction
|
567
|
-
@pirate.ship.name = ''
|
568
|
-
assert !@pirate.valid?
|
569
|
-
|
570
|
-
@pirate.ship.mark_for_destruction
|
571
|
-
@pirate.ship.expects(:valid?).never
|
572
|
-
assert_difference('Ship.count', -1) { @pirate.save! }
|
573
|
-
end
|
574
|
-
|
575
|
-
def test_a_child_marked_for_destruction_should_not_be_destroyed_twice
|
576
|
-
@pirate.ship.mark_for_destruction
|
577
|
-
assert @pirate.save
|
578
|
-
@pirate.ship.expects(:destroy).never
|
579
|
-
assert @pirate.save
|
580
|
-
end
|
581
|
-
|
582
|
-
def test_should_rollback_destructions_if_an_exception_occurred_while_saving_a_child
|
583
|
-
# Stub the save method of the @pirate.ship instance to destroy and then raise an exception
|
584
|
-
class << @pirate.ship
|
585
|
-
def save(*args)
|
586
|
-
super
|
587
|
-
destroy
|
588
|
-
raise 'Oh noes!'
|
589
|
-
end
|
590
|
-
end
|
591
|
-
|
592
|
-
assert_raise(RuntimeError) { assert !@pirate.save }
|
593
|
-
assert_not_nil @pirate.reload.ship
|
594
|
-
end
|
595
|
-
|
596
|
-
# belongs_to
|
597
|
-
def test_should_destroy_a_parent_association_as_part_of_the_save_transaction_if_it_was_marked_for_destroyal
|
598
|
-
assert !@ship.pirate.marked_for_destruction?
|
599
|
-
|
600
|
-
@ship.pirate.mark_for_destruction
|
601
|
-
id = @ship.pirate.id
|
602
|
-
|
603
|
-
assert @ship.pirate.marked_for_destruction?
|
604
|
-
assert Pirate.find_by_id(id)
|
605
|
-
|
606
|
-
@ship.save
|
607
|
-
assert_nil @ship.reload.pirate
|
608
|
-
assert_nil Pirate.find_by_id(id)
|
609
|
-
end
|
610
|
-
|
611
|
-
def test_should_skip_validation_on_a_parent_association_if_marked_for_destruction
|
612
|
-
@ship.pirate.catchphrase = ''
|
613
|
-
assert !@ship.valid?
|
614
|
-
|
615
|
-
@ship.pirate.mark_for_destruction
|
616
|
-
@ship.pirate.expects(:valid?).never
|
617
|
-
assert_difference('Pirate.count', -1) { @ship.save! }
|
618
|
-
end
|
619
|
-
|
620
|
-
def test_a_parent_marked_for_destruction_should_not_be_destroyed_twice
|
621
|
-
@ship.pirate.mark_for_destruction
|
622
|
-
assert @ship.save
|
623
|
-
@ship.pirate.expects(:destroy).never
|
624
|
-
assert @ship.save
|
625
|
-
end
|
626
|
-
|
627
|
-
def test_should_rollback_destructions_if_an_exception_occurred_while_saving_a_parent
|
628
|
-
# Stub the save method of the @ship.pirate instance to destroy and then raise an exception
|
629
|
-
class << @ship.pirate
|
630
|
-
def save(*args)
|
631
|
-
super
|
632
|
-
destroy
|
633
|
-
raise 'Oh noes!'
|
634
|
-
end
|
635
|
-
end
|
636
|
-
|
637
|
-
assert_raise(RuntimeError) { assert !@ship.save }
|
638
|
-
assert_not_nil @ship.reload.pirate
|
639
|
-
end
|
640
|
-
|
641
|
-
# has_many & has_and_belongs_to
|
642
|
-
%w{ parrots birds }.each do |association_name|
|
643
|
-
define_method("test_should_destroy_#{association_name}_as_part_of_the_save_transaction_if_they_were_marked_for_destroyal") do
|
644
|
-
2.times { |i| @pirate.send(association_name).create!(:name => "#{association_name}_#{i}") }
|
645
|
-
|
646
|
-
assert !@pirate.send(association_name).any? { |child| child.marked_for_destruction? }
|
647
|
-
|
648
|
-
@pirate.send(association_name).each { |child| child.mark_for_destruction }
|
649
|
-
klass = @pirate.send(association_name).first.class
|
650
|
-
ids = @pirate.send(association_name).map(&:id)
|
651
|
-
|
652
|
-
assert @pirate.send(association_name).all? { |child| child.marked_for_destruction? }
|
653
|
-
ids.each { |id| assert klass.find_by_id(id) }
|
654
|
-
|
655
|
-
@pirate.save
|
656
|
-
assert @pirate.reload.send(association_name).empty?
|
657
|
-
ids.each { |id| assert_nil klass.find_by_id(id) }
|
658
|
-
end
|
659
|
-
|
660
|
-
define_method("test_should_skip_validation_on_the_#{association_name}_association_if_marked_for_destruction") do
|
661
|
-
2.times { |i| @pirate.send(association_name).create!(:name => "#{association_name}_#{i}") }
|
662
|
-
children = @pirate.send(association_name)
|
663
|
-
|
664
|
-
children.each { |child| child.name = '' }
|
665
|
-
assert !@pirate.valid?
|
666
|
-
|
667
|
-
children.each do |child|
|
668
|
-
child.mark_for_destruction
|
669
|
-
child.expects(:valid?).never
|
670
|
-
end
|
671
|
-
assert_difference("#{association_name.classify}.count", -2) { @pirate.save! }
|
672
|
-
end
|
673
|
-
|
674
|
-
define_method("test_should_skip_validation_on_the_#{association_name}_association_if_destroyed") do
|
675
|
-
@pirate.send(association_name).create!(:name => "#{association_name}_1")
|
676
|
-
children = @pirate.send(association_name)
|
677
|
-
|
678
|
-
children.each { |child| child.name = '' }
|
679
|
-
assert !@pirate.valid?
|
680
|
-
|
681
|
-
children.each { |child| child.destroy }
|
682
|
-
assert @pirate.valid?
|
683
|
-
end
|
684
|
-
|
685
|
-
define_method("test_a_child_marked_for_destruction_should_not_be_destroyed_twice_while_saving_#{association_name}") do
|
686
|
-
@pirate.send(association_name).create!(:name => "#{association_name}_1")
|
687
|
-
children = @pirate.send(association_name)
|
688
|
-
|
689
|
-
children.each { |child| child.mark_for_destruction }
|
690
|
-
assert @pirate.save
|
691
|
-
children.each { |child| child.expects(:destroy).never }
|
692
|
-
assert @pirate.save
|
693
|
-
end
|
694
|
-
|
695
|
-
define_method("test_should_rollback_destructions_if_an_exception_occurred_while_saving_#{association_name}") do
|
696
|
-
2.times { |i| @pirate.send(association_name).create!(:name => "#{association_name}_#{i}") }
|
697
|
-
before = @pirate.send(association_name).map { |c| c.mark_for_destruction ; c }
|
698
|
-
|
699
|
-
# Stub the destroy method of the the second child to raise an exception
|
700
|
-
class << before.last
|
701
|
-
def destroy(*args)
|
702
|
-
super
|
703
|
-
raise 'Oh noes!'
|
704
|
-
end
|
705
|
-
end
|
706
|
-
|
707
|
-
assert_raise(RuntimeError) { assert !@pirate.save }
|
708
|
-
assert before.first.frozen? # the first child was indeed destroyed
|
709
|
-
assert_equal before, @pirate.reload.send(association_name)
|
710
|
-
end
|
711
|
-
|
712
|
-
# Add and remove callbacks tests for association collections.
|
713
|
-
%w{ method proc }.each do |callback_type|
|
714
|
-
define_method("test_should_run_add_callback_#{callback_type}s_for_#{association_name}") do
|
715
|
-
association_name_with_callbacks = "#{association_name}_with_#{callback_type}_callbacks"
|
716
|
-
|
717
|
-
pirate = Pirate.new(:catchphrase => "Arr")
|
718
|
-
pirate.send(association_name_with_callbacks).build(:name => "Crowe the One-Eyed")
|
719
|
-
|
720
|
-
expected = [
|
721
|
-
"before_adding_#{callback_type}_#{association_name.singularize}_<new>",
|
722
|
-
"after_adding_#{callback_type}_#{association_name.singularize}_<new>"
|
723
|
-
]
|
724
|
-
|
725
|
-
assert_equal expected, pirate.ship_log
|
726
|
-
end
|
727
|
-
|
728
|
-
define_method("test_should_run_remove_callback_#{callback_type}s_for_#{association_name}") do
|
729
|
-
association_name_with_callbacks = "#{association_name}_with_#{callback_type}_callbacks"
|
730
|
-
|
731
|
-
@pirate.send(association_name_with_callbacks).create!(:name => "Crowe the One-Eyed")
|
732
|
-
@pirate.send(association_name_with_callbacks).each { |c| c.mark_for_destruction }
|
733
|
-
child_id = @pirate.send(association_name_with_callbacks).first.id
|
734
|
-
|
735
|
-
@pirate.ship_log.clear
|
736
|
-
@pirate.save
|
737
|
-
|
738
|
-
expected = [
|
739
|
-
"before_removing_#{callback_type}_#{association_name.singularize}_#{child_id}",
|
740
|
-
"after_removing_#{callback_type}_#{association_name.singularize}_#{child_id}"
|
741
|
-
]
|
742
|
-
|
743
|
-
assert_equal expected, @pirate.ship_log
|
744
|
-
end
|
745
|
-
end
|
746
|
-
end
|
747
|
-
end
|
748
|
-
|
749
|
-
class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
|
750
|
-
self.use_transactional_fixtures = false
|
751
|
-
|
752
|
-
def setup
|
753
|
-
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
754
|
-
@ship = @pirate.create_ship(:name => 'Nights Dirty Lightning')
|
755
|
-
end
|
756
|
-
|
757
|
-
def test_should_still_work_without_an_associated_model
|
758
|
-
@ship.destroy
|
759
|
-
@pirate.reload.catchphrase = "Arr"
|
760
|
-
@pirate.save
|
761
|
-
assert 'Arr', @pirate.reload.catchphrase
|
762
|
-
end
|
763
|
-
|
764
|
-
def test_should_automatically_save_the_associated_model
|
765
|
-
@pirate.ship.name = 'The Vile Insanity'
|
766
|
-
@pirate.save
|
767
|
-
assert_equal 'The Vile Insanity', @pirate.reload.ship.name
|
768
|
-
end
|
769
|
-
|
770
|
-
def test_should_automatically_save_bang_the_associated_model
|
771
|
-
@pirate.ship.name = 'The Vile Insanity'
|
772
|
-
@pirate.save!
|
773
|
-
assert_equal 'The Vile Insanity', @pirate.reload.ship.name
|
774
|
-
end
|
775
|
-
|
776
|
-
def test_should_automatically_validate_the_associated_model
|
777
|
-
@pirate.ship.name = ''
|
778
|
-
assert !@pirate.valid?
|
779
|
-
assert_equal "can't be blank", @pirate.errors.on(:"ship.name")
|
780
|
-
end
|
781
|
-
|
782
|
-
def test_should_merge_errors_on_the_associated_models_onto_the_parent_even_if_it_is_not_valid
|
783
|
-
@pirate.ship.name = nil
|
784
|
-
@pirate.catchphrase = nil
|
785
|
-
assert !@pirate.valid?
|
786
|
-
assert @pirate.errors.full_messages.include?("Name can't be blank")
|
787
|
-
assert @pirate.errors.full_messages.include?("Catchphrase can't be blank")
|
788
|
-
end
|
789
|
-
|
790
|
-
def test_should_still_allow_to_bypass_validations_on_the_associated_model
|
791
|
-
@pirate.catchphrase = ''
|
792
|
-
@pirate.ship.name = ''
|
793
|
-
@pirate.save(false)
|
794
|
-
assert_equal ['', ''], [@pirate.reload.catchphrase, @pirate.ship.name]
|
795
|
-
end
|
796
|
-
|
797
|
-
def test_should_allow_to_bypass_validations_on_associated_models_at_any_depth
|
798
|
-
2.times { |i| @pirate.ship.parts.create!(:name => "part #{i}") }
|
799
|
-
|
800
|
-
@pirate.catchphrase = ''
|
801
|
-
@pirate.ship.name = ''
|
802
|
-
@pirate.ship.parts.each { |part| part.name = '' }
|
803
|
-
@pirate.save(false)
|
804
|
-
|
805
|
-
values = [@pirate.reload.catchphrase, @pirate.ship.name, *@pirate.ship.parts.map(&:name)]
|
806
|
-
assert_equal ['', '', '', ''], values
|
807
|
-
end
|
808
|
-
|
809
|
-
def test_should_still_raise_an_ActiveRecordRecord_Invalid_exception_if_we_want_that
|
810
|
-
@pirate.ship.name = ''
|
811
|
-
assert_raise(ActiveRecord::RecordInvalid) do
|
812
|
-
@pirate.save!
|
813
|
-
end
|
814
|
-
end
|
815
|
-
|
816
|
-
def test_should_not_save_and_return_false_if_a_callback_cancelled_saving
|
817
|
-
pirate = Pirate.new(:catchphrase => 'Arr')
|
818
|
-
ship = pirate.build_ship(:name => 'The Vile Insanity')
|
819
|
-
ship.cancel_save_from_callback = true
|
820
|
-
|
821
|
-
assert_no_difference 'Pirate.count' do
|
822
|
-
assert_no_difference 'Ship.count' do
|
823
|
-
assert !pirate.save
|
824
|
-
end
|
825
|
-
end
|
826
|
-
end
|
827
|
-
|
828
|
-
def test_should_rollback_any_changes_if_an_exception_occurred_while_saving
|
829
|
-
before = [@pirate.catchphrase, @pirate.ship.name]
|
830
|
-
|
831
|
-
@pirate.catchphrase = 'Arr'
|
832
|
-
@pirate.ship.name = 'The Vile Insanity'
|
833
|
-
|
834
|
-
# Stub the save method of the @pirate.ship instance to raise an exception
|
835
|
-
class << @pirate.ship
|
836
|
-
def save(*args)
|
837
|
-
super
|
838
|
-
raise 'Oh noes!'
|
839
|
-
end
|
840
|
-
end
|
841
|
-
|
842
|
-
assert_raise(RuntimeError) { assert !@pirate.save }
|
843
|
-
assert_equal before, [@pirate.reload.catchphrase, @pirate.ship.name]
|
844
|
-
end
|
845
|
-
|
846
|
-
def test_should_not_load_the_associated_model
|
847
|
-
assert_queries(1) { @pirate.catchphrase = 'Arr'; @pirate.save! }
|
848
|
-
end
|
849
|
-
end
|
850
|
-
|
851
|
-
class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase
|
852
|
-
self.use_transactional_fixtures = false
|
853
|
-
|
854
|
-
def setup
|
855
|
-
@ship = Ship.create(:name => 'Nights Dirty Lightning')
|
856
|
-
@pirate = @ship.create_pirate(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
857
|
-
end
|
858
|
-
|
859
|
-
def test_should_still_work_without_an_associated_model
|
860
|
-
@pirate.destroy
|
861
|
-
@ship.reload.name = "The Vile Insanity"
|
862
|
-
@ship.save
|
863
|
-
assert 'The Vile Insanity', @ship.reload.name
|
864
|
-
end
|
865
|
-
|
866
|
-
def test_should_automatically_save_the_associated_model
|
867
|
-
@ship.pirate.catchphrase = 'Arr'
|
868
|
-
@ship.save
|
869
|
-
assert_equal 'Arr', @ship.reload.pirate.catchphrase
|
870
|
-
end
|
871
|
-
|
872
|
-
def test_should_automatically_save_bang_the_associated_model
|
873
|
-
@ship.pirate.catchphrase = 'Arr'
|
874
|
-
@ship.save!
|
875
|
-
assert_equal 'Arr', @ship.reload.pirate.catchphrase
|
876
|
-
end
|
877
|
-
|
878
|
-
def test_should_automatically_validate_the_associated_model
|
879
|
-
@ship.pirate.catchphrase = ''
|
880
|
-
assert !@ship.valid?
|
881
|
-
assert_equal "can't be blank", @ship.errors.on(:"pirate.catchphrase")
|
882
|
-
end
|
883
|
-
|
884
|
-
def test_should_merge_errors_on_the_associated_model_onto_the_parent_even_if_it_is_not_valid
|
885
|
-
@ship.name = nil
|
886
|
-
@ship.pirate.catchphrase = nil
|
887
|
-
assert !@ship.valid?
|
888
|
-
assert @ship.errors.full_messages.include?("Name can't be blank")
|
889
|
-
assert @ship.errors.full_messages.include?("Catchphrase can't be blank")
|
890
|
-
end
|
891
|
-
|
892
|
-
def test_should_still_allow_to_bypass_validations_on_the_associated_model
|
893
|
-
@ship.pirate.catchphrase = ''
|
894
|
-
@ship.name = ''
|
895
|
-
@ship.save(false)
|
896
|
-
assert_equal ['', ''], [@ship.reload.name, @ship.pirate.catchphrase]
|
897
|
-
end
|
898
|
-
|
899
|
-
def test_should_still_raise_an_ActiveRecordRecord_Invalid_exception_if_we_want_that
|
900
|
-
@ship.pirate.catchphrase = ''
|
901
|
-
assert_raise(ActiveRecord::RecordInvalid) do
|
902
|
-
@ship.save!
|
903
|
-
end
|
904
|
-
end
|
905
|
-
|
906
|
-
def test_should_not_save_and_return_false_if_a_callback_cancelled_saving
|
907
|
-
ship = Ship.new(:name => 'The Vile Insanity')
|
908
|
-
pirate = ship.build_pirate(:catchphrase => 'Arr')
|
909
|
-
pirate.cancel_save_from_callback = true
|
910
|
-
|
911
|
-
assert_no_difference 'Ship.count' do
|
912
|
-
assert_no_difference 'Pirate.count' do
|
913
|
-
assert !ship.save
|
914
|
-
end
|
915
|
-
end
|
916
|
-
end
|
917
|
-
|
918
|
-
def test_should_rollback_any_changes_if_an_exception_occurred_while_saving
|
919
|
-
before = [@ship.pirate.catchphrase, @ship.name]
|
920
|
-
|
921
|
-
@ship.pirate.catchphrase = 'Arr'
|
922
|
-
@ship.name = 'The Vile Insanity'
|
923
|
-
|
924
|
-
# Stub the save method of the @ship.pirate instance to raise an exception
|
925
|
-
class << @ship.pirate
|
926
|
-
def save(*args)
|
927
|
-
super
|
928
|
-
raise 'Oh noes!'
|
929
|
-
end
|
930
|
-
end
|
931
|
-
|
932
|
-
assert_raise(RuntimeError) { assert !@ship.save }
|
933
|
-
assert_equal before, [@ship.pirate.reload.catchphrase, @ship.reload.name]
|
934
|
-
end
|
935
|
-
|
936
|
-
def test_should_not_load_the_associated_model
|
937
|
-
assert_queries(1) { @ship.name = 'The Vile Insanity'; @ship.save! }
|
938
|
-
end
|
939
|
-
end
|
940
|
-
|
941
|
-
module AutosaveAssociationOnACollectionAssociationTests
|
942
|
-
def test_should_automatically_save_the_associated_models
|
943
|
-
new_names = ['Grace OMalley', 'Privateers Greed']
|
944
|
-
@pirate.send(@association_name).each_with_index { |child, i| child.name = new_names[i] }
|
945
|
-
|
946
|
-
@pirate.save
|
947
|
-
assert_equal new_names, @pirate.reload.send(@association_name).map(&:name)
|
948
|
-
end
|
949
|
-
|
950
|
-
def test_should_automatically_save_bang_the_associated_models
|
951
|
-
new_names = ['Grace OMalley', 'Privateers Greed']
|
952
|
-
@pirate.send(@association_name).each_with_index { |child, i| child.name = new_names[i] }
|
953
|
-
|
954
|
-
@pirate.save!
|
955
|
-
assert_equal new_names, @pirate.reload.send(@association_name).map(&:name)
|
956
|
-
end
|
957
|
-
|
958
|
-
def test_should_automatically_validate_the_associated_models
|
959
|
-
@pirate.send(@association_name).each { |child| child.name = '' }
|
960
|
-
|
961
|
-
assert !@pirate.valid?
|
962
|
-
assert @pirate.errors.full_messages.include?("Name can't be blank")
|
963
|
-
assert @pirate.errors.on(@association_name).blank?
|
964
|
-
end
|
965
|
-
|
966
|
-
def test_should_not_use_default_invalid_error_on_associated_models
|
967
|
-
@pirate.send(@association_name).build(:name => '')
|
968
|
-
|
969
|
-
assert !@pirate.valid?
|
970
|
-
assert_equal "can't be blank", @pirate.errors.on("#{@association_name}.name")
|
971
|
-
assert @pirate.errors.on(@association_name).blank?
|
972
|
-
end
|
973
|
-
|
974
|
-
def test_should_merge_errors_on_the_associated_models_onto_the_parent_even_if_it_is_not_valid
|
975
|
-
@pirate.send(@association_name).each { |child| child.name = '' }
|
976
|
-
@pirate.catchphrase = nil
|
977
|
-
|
978
|
-
assert !@pirate.valid?
|
979
|
-
assert_equal "can't be blank", @pirate.errors.on("#{@association_name}.name")
|
980
|
-
assert !@pirate.errors.on(:catchphrase).blank?
|
981
|
-
end
|
982
|
-
|
983
|
-
def test_should_allow_to_bypass_validations_on_the_associated_models_on_update
|
984
|
-
@pirate.catchphrase = ''
|
985
|
-
@pirate.send(@association_name).each { |child| child.name = '' }
|
986
|
-
|
987
|
-
assert @pirate.save(false)
|
988
|
-
assert_equal ['', '', ''], [
|
989
|
-
@pirate.reload.catchphrase,
|
990
|
-
@pirate.send(@association_name).first.name,
|
991
|
-
@pirate.send(@association_name).last.name
|
992
|
-
]
|
993
|
-
end
|
994
|
-
|
995
|
-
def test_should_validation_the_associated_models_on_create
|
996
|
-
assert_no_difference("#{ @association_name == :birds ? 'Bird' : 'Parrot' }.count") do
|
997
|
-
2.times { @pirate.send(@association_name).build }
|
998
|
-
@pirate.save(true)
|
999
|
-
end
|
1000
|
-
end
|
1001
|
-
|
1002
|
-
def test_should_allow_to_bypass_validations_on_the_associated_models_on_create
|
1003
|
-
assert_difference("#{ @association_name == :birds ? 'Bird' : 'Parrot' }.count", +2) do
|
1004
|
-
2.times { @pirate.send(@association_name).build }
|
1005
|
-
@pirate.save(false)
|
1006
|
-
end
|
1007
|
-
end
|
1008
|
-
|
1009
|
-
def test_should_not_save_and_return_false_if_a_callback_cancelled_saving_in_either_create_or_update
|
1010
|
-
@pirate.catchphrase = 'Changed'
|
1011
|
-
@child_1.name = 'Changed'
|
1012
|
-
@child_1.cancel_save_from_callback = true
|
1013
|
-
|
1014
|
-
assert !@pirate.save
|
1015
|
-
assert_equal "Don' botharrr talkin' like one, savvy?", @pirate.reload.catchphrase
|
1016
|
-
assert_equal "Posideons Killer", @child_1.reload.name
|
1017
|
-
|
1018
|
-
new_pirate = Pirate.new(:catchphrase => 'Arr')
|
1019
|
-
new_child = new_pirate.send(@association_name).build(:name => 'Grace OMalley')
|
1020
|
-
new_child.cancel_save_from_callback = true
|
1021
|
-
|
1022
|
-
assert_no_difference 'Pirate.count' do
|
1023
|
-
assert_no_difference "#{new_child.class.name}.count" do
|
1024
|
-
assert !new_pirate.save
|
1025
|
-
end
|
1026
|
-
end
|
1027
|
-
end
|
1028
|
-
|
1029
|
-
def test_should_rollback_any_changes_if_an_exception_occurred_while_saving
|
1030
|
-
before = [@pirate.catchphrase, *@pirate.send(@association_name).map(&:name)]
|
1031
|
-
new_names = ['Grace OMalley', 'Privateers Greed']
|
1032
|
-
|
1033
|
-
@pirate.catchphrase = 'Arr'
|
1034
|
-
@pirate.send(@association_name).each_with_index { |child, i| child.name = new_names[i] }
|
1035
|
-
|
1036
|
-
# Stub the save method of the first child instance to raise an exception
|
1037
|
-
class << @pirate.send(@association_name).first
|
1038
|
-
def save(*args)
|
1039
|
-
super
|
1040
|
-
raise 'Oh noes!'
|
1041
|
-
end
|
1042
|
-
end
|
1043
|
-
|
1044
|
-
assert_raise(RuntimeError) { assert !@pirate.save }
|
1045
|
-
assert_equal before, [@pirate.reload.catchphrase, *@pirate.send(@association_name).map(&:name)]
|
1046
|
-
end
|
1047
|
-
|
1048
|
-
def test_should_still_raise_an_ActiveRecordRecord_Invalid_exception_if_we_want_that
|
1049
|
-
@pirate.send(@association_name).each { |child| child.name = '' }
|
1050
|
-
assert_raise(ActiveRecord::RecordInvalid) do
|
1051
|
-
@pirate.save!
|
1052
|
-
end
|
1053
|
-
end
|
1054
|
-
|
1055
|
-
def test_should_not_load_the_associated_models_if_they_were_not_loaded_yet
|
1056
|
-
assert_queries(1) { @pirate.catchphrase = 'Arr'; @pirate.save! }
|
1057
|
-
|
1058
|
-
@pirate.send(@association_name).class # hack to load the target
|
1059
|
-
|
1060
|
-
assert_queries(3) do
|
1061
|
-
@pirate.catchphrase = 'Yarr'
|
1062
|
-
new_names = ['Grace OMalley', 'Privateers Greed']
|
1063
|
-
@pirate.send(@association_name).each_with_index { |child, i| child.name = new_names[i] }
|
1064
|
-
@pirate.save!
|
1065
|
-
end
|
1066
|
-
end
|
1067
|
-
end
|
1068
|
-
|
1069
|
-
class TestAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase
|
1070
|
-
self.use_transactional_fixtures = false
|
1071
|
-
|
1072
|
-
def setup
|
1073
|
-
@association_name = :birds
|
1074
|
-
|
1075
|
-
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
1076
|
-
@child_1 = @pirate.birds.create(:name => 'Posideons Killer')
|
1077
|
-
@child_2 = @pirate.birds.create(:name => 'Killer bandita Dionne')
|
1078
|
-
end
|
1079
|
-
|
1080
|
-
include AutosaveAssociationOnACollectionAssociationTests
|
1081
|
-
end
|
1082
|
-
|
1083
|
-
class TestAutosaveAssociationOnAHasAndBelongsToManyAssociation < ActiveRecord::TestCase
|
1084
|
-
self.use_transactional_fixtures = false
|
1085
|
-
|
1086
|
-
def setup
|
1087
|
-
@association_name = :parrots
|
1088
|
-
@habtm = true
|
1089
|
-
|
1090
|
-
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
1091
|
-
@child_1 = @pirate.parrots.create(:name => 'Posideons Killer')
|
1092
|
-
@child_2 = @pirate.parrots.create(:name => 'Killer bandita Dionne')
|
1093
|
-
end
|
1094
|
-
|
1095
|
-
include AutosaveAssociationOnACollectionAssociationTests
|
1096
|
-
end
|
1097
|
-
|
1098
|
-
class TestAutosaveAssociationValidationsOnAHasManyAssocication < ActiveRecord::TestCase
|
1099
|
-
self.use_transactional_fixtures = false
|
1100
|
-
|
1101
|
-
def setup
|
1102
|
-
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
1103
|
-
@pirate.birds.create(:name => 'cookoo')
|
1104
|
-
end
|
1105
|
-
|
1106
|
-
test "should automatically validate associations" do
|
1107
|
-
assert @pirate.valid?
|
1108
|
-
@pirate.birds.each { |bird| bird.name = '' }
|
1109
|
-
|
1110
|
-
assert !@pirate.valid?
|
1111
|
-
end
|
1112
|
-
end
|
1113
|
-
|
1114
|
-
class TestAutosaveAssociationValidationsOnAHasOneAssocication < ActiveRecord::TestCase
|
1115
|
-
self.use_transactional_fixtures = false
|
1116
|
-
|
1117
|
-
def setup
|
1118
|
-
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
1119
|
-
@pirate.create_ship(:name => 'titanic')
|
1120
|
-
end
|
1121
|
-
|
1122
|
-
test "should automatically validate associations with :validate => true" do
|
1123
|
-
assert @pirate.valid?
|
1124
|
-
@pirate.ship.name = ''
|
1125
|
-
assert !@pirate.valid?
|
1126
|
-
end
|
1127
|
-
|
1128
|
-
test "should not automatically validate associations without :validate => true" do
|
1129
|
-
assert @pirate.valid?
|
1130
|
-
@pirate.non_validated_ship.name = ''
|
1131
|
-
assert @pirate.valid?
|
1132
|
-
end
|
1133
|
-
end
|
1134
|
-
|
1135
|
-
class TestAutosaveAssociationValidationsOnABelongsToAssocication < ActiveRecord::TestCase
|
1136
|
-
self.use_transactional_fixtures = false
|
1137
|
-
|
1138
|
-
def setup
|
1139
|
-
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
1140
|
-
end
|
1141
|
-
|
1142
|
-
test "should automatically validate associations with :validate => true" do
|
1143
|
-
assert @pirate.valid?
|
1144
|
-
@pirate.parrot = Parrot.new(:name => '')
|
1145
|
-
assert !@pirate.valid?
|
1146
|
-
end
|
1147
|
-
|
1148
|
-
test "should not automatically validate associations without :validate => true" do
|
1149
|
-
assert @pirate.valid?
|
1150
|
-
@pirate.non_validated_parrot = Parrot.new(:name => '')
|
1151
|
-
assert @pirate.valid?
|
1152
|
-
end
|
1153
|
-
end
|
1154
|
-
|
1155
|
-
class TestAutosaveAssociationValidationsOnAHABTMAssocication < ActiveRecord::TestCase
|
1156
|
-
self.use_transactional_fixtures = false
|
1157
|
-
|
1158
|
-
def setup
|
1159
|
-
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
1160
|
-
end
|
1161
|
-
|
1162
|
-
test "should automatically validate associations with :validate => true" do
|
1163
|
-
assert @pirate.valid?
|
1164
|
-
@pirate.parrots = [ Parrot.new(:name => 'popuga') ]
|
1165
|
-
@pirate.parrots.each { |parrot| parrot.name = '' }
|
1166
|
-
assert !@pirate.valid?
|
1167
|
-
end
|
1168
|
-
|
1169
|
-
test "should not automatically validate associations without :validate => true" do
|
1170
|
-
assert @pirate.valid?
|
1171
|
-
@pirate.non_validated_parrots = [ Parrot.new(:name => 'popuga') ]
|
1172
|
-
@pirate.non_validated_parrots.each { |parrot| parrot.name = '' }
|
1173
|
-
assert @pirate.valid?
|
1174
|
-
end
|
1175
|
-
end
|
1176
|
-
|
1177
|
-
class TestAutosaveAssociationValidationMethodsGeneration < ActiveRecord::TestCase
|
1178
|
-
self.use_transactional_fixtures = false
|
1179
|
-
|
1180
|
-
def setup
|
1181
|
-
@pirate = Pirate.new
|
1182
|
-
end
|
1183
|
-
|
1184
|
-
test "should generate validation methods for has_many associations" do
|
1185
|
-
assert @pirate.respond_to?(:validate_associated_records_for_birds)
|
1186
|
-
end
|
1187
|
-
|
1188
|
-
test "should generate validation methods for has_one associations with :validate => true" do
|
1189
|
-
assert @pirate.respond_to?(:validate_associated_records_for_ship)
|
1190
|
-
end
|
1191
|
-
|
1192
|
-
test "should not generate validation methods for has_one associations without :validate => true" do
|
1193
|
-
assert !@pirate.respond_to?(:validate_associated_records_for_non_validated_ship)
|
1194
|
-
end
|
1195
|
-
|
1196
|
-
test "should generate validation methods for belongs_to associations with :validate => true" do
|
1197
|
-
assert @pirate.respond_to?(:validate_associated_records_for_parrot)
|
1198
|
-
end
|
1199
|
-
|
1200
|
-
test "should not generate validation methods for belongs_to associations without :validate => true" do
|
1201
|
-
assert !@pirate.respond_to?(:validate_associated_records_for_non_validated_parrot)
|
1202
|
-
end
|
1203
|
-
|
1204
|
-
test "should generate validation methods for HABTM associations with :validate => true" do
|
1205
|
-
assert @pirate.respond_to?(:validate_associated_records_for_parrots)
|
1206
|
-
end
|
1207
|
-
|
1208
|
-
test "should not generate validation methods for HABTM associations without :validate => true" do
|
1209
|
-
assert !@pirate.respond_to?(:validate_associated_records_for_non_validated_parrots)
|
1210
|
-
end
|
1211
|
-
end
|
1212
|
-
|
1213
|
-
class TestAutosaveAssociationWithTouch < ActiveRecord::TestCase
|
1214
|
-
def test_autosave_with_touch_should_not_raise_system_stack_error
|
1215
|
-
invoice = Invoice.create
|
1216
|
-
assert_nothing_raised { invoice.line_items.create(:amount => 10) }
|
1217
|
-
end
|
1218
|
-
end
|