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,403 +1,275 @@
|
|
1
|
+
require 'active_support/core_ext/enumerable'
|
2
|
+
require 'active_support/deprecation'
|
3
|
+
|
1
4
|
module ActiveRecord
|
5
|
+
# = Active Record Attribute Methods
|
2
6
|
module AttributeMethods #:nodoc:
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
# #{attr}#{suffix}(*args, &block)
|
23
|
-
#
|
24
|
-
# to
|
25
|
-
#
|
26
|
-
# attribute#{suffix}(#{attr}, *args, &block)
|
27
|
-
#
|
28
|
-
# An <tt>attribute#{suffix}</tt> instance method must exist and accept at least
|
29
|
-
# the +attr+ argument.
|
30
|
-
#
|
31
|
-
# For example:
|
32
|
-
#
|
33
|
-
# class Person < ActiveRecord::Base
|
34
|
-
# attribute_method_suffix '_changed?'
|
35
|
-
#
|
36
|
-
# private
|
37
|
-
# def attribute_changed?(attr)
|
38
|
-
# ...
|
39
|
-
# end
|
40
|
-
# end
|
41
|
-
#
|
42
|
-
# person = Person.find(1)
|
43
|
-
# person.name_changed? # => false
|
44
|
-
# person.name = 'Hubert'
|
45
|
-
# person.name_changed? # => true
|
46
|
-
def attribute_method_suffix(*suffixes)
|
47
|
-
attribute_method_suffixes.concat suffixes
|
48
|
-
rebuild_attribute_method_regexp
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
include ActiveModel::AttributeMethods
|
9
|
+
|
10
|
+
included do
|
11
|
+
include Read
|
12
|
+
include Write
|
13
|
+
include BeforeTypeCast
|
14
|
+
include Query
|
15
|
+
include PrimaryKey
|
16
|
+
include TimeZoneConversion
|
17
|
+
include Dirty
|
18
|
+
include Serialization
|
19
|
+
include DeprecatedUnderscoreRead
|
20
|
+
|
21
|
+
# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
|
22
|
+
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
|
23
|
+
# (Alias for the protected read_attribute method).
|
24
|
+
def [](attr_name)
|
25
|
+
read_attribute(attr_name)
|
49
26
|
end
|
50
27
|
|
51
|
-
#
|
52
|
-
|
53
|
-
|
54
|
-
|
28
|
+
# Updates the attribute identified by <tt>attr_name</tt> with the specified +value+.
|
29
|
+
# (Alias for the protected write_attribute method).
|
30
|
+
def []=(attr_name, value)
|
31
|
+
write_attribute(attr_name, value)
|
55
32
|
end
|
33
|
+
end
|
56
34
|
|
57
|
-
|
58
|
-
# Contains the names of the generated attribute methods.
|
59
|
-
def generated_methods #:nodoc:
|
60
|
-
@generated_methods ||= Set.new
|
61
|
-
end
|
62
|
-
|
63
|
-
def generated_methods?
|
64
|
-
!generated_methods.empty?
|
65
|
-
end
|
66
|
-
|
35
|
+
module ClassMethods
|
67
36
|
# Generates all the attribute related methods for columns in the database
|
68
37
|
# accessors, mutators and query methods.
|
69
38
|
def define_attribute_methods
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
39
|
+
unless defined?(@attribute_methods_mutex)
|
40
|
+
msg = "It looks like something (probably a gem/plugin) is overriding the " \
|
41
|
+
"ActiveRecord::Base.inherited method. It is important that this hook executes so " \
|
42
|
+
"that your models are set up correctly. A workaround has been added to stop this " \
|
43
|
+
"causing an error in 3.2, but future versions will simply not work if the hook is " \
|
44
|
+
"overridden. If you are using Kaminari, please upgrade as it is known to have had " \
|
45
|
+
"this problem.\n\n"
|
46
|
+
msg << "The following may help track down the problem:"
|
47
|
+
|
48
|
+
meth = method(:inherited)
|
49
|
+
if meth.respond_to?(:source_location)
|
50
|
+
msg << " #{meth.source_location.inspect}"
|
51
|
+
else
|
52
|
+
msg << " #{meth.inspect}"
|
80
53
|
end
|
54
|
+
msg << "\n\n"
|
81
55
|
|
82
|
-
|
83
|
-
if self.serialized_attributes[name]
|
84
|
-
define_write_method_for_serialized_attribute(name)
|
85
|
-
elsif create_time_zone_conversion_attribute?(name, column)
|
86
|
-
define_write_method_for_time_zone_conversion(name)
|
87
|
-
else
|
88
|
-
define_write_method(name.to_sym)
|
89
|
-
end
|
90
|
-
end
|
56
|
+
ActiveSupport::Deprecation.warn(msg)
|
91
57
|
|
92
|
-
|
93
|
-
define_question_method(name)
|
94
|
-
end
|
58
|
+
@attribute_methods_mutex = Mutex.new
|
95
59
|
end
|
96
|
-
end
|
97
60
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
@_defined_class_methods.include?(method_name)
|
108
|
-
end
|
109
|
-
|
110
|
-
alias :define_read_methods :define_attribute_methods
|
111
|
-
|
112
|
-
# +cache_attributes+ allows you to declare which converted attribute values should
|
113
|
-
# be cached. Usually caching only pays off for attributes with expensive conversion
|
114
|
-
# methods, like time related columns (e.g. +created_at+, +updated_at+).
|
115
|
-
def cache_attributes(*attribute_names)
|
116
|
-
attribute_names.each {|attr| cached_attributes << attr.to_s}
|
61
|
+
# Use a mutex; we don't want two thread simaltaneously trying to define
|
62
|
+
# attribute methods.
|
63
|
+
@attribute_methods_mutex.synchronize do
|
64
|
+
return if attribute_methods_generated?
|
65
|
+
superclass.define_attribute_methods unless self == base_class
|
66
|
+
super(column_names)
|
67
|
+
column_names.each { |name| define_external_attribute_method(name) }
|
68
|
+
@attribute_methods_generated = true
|
69
|
+
end
|
117
70
|
end
|
118
71
|
|
119
|
-
|
120
|
-
|
121
|
-
def cached_attributes
|
122
|
-
@cached_attributes ||=
|
123
|
-
columns.select{|c| attribute_types_cached_by_default.include?(c.type)}.map(&:name).to_set
|
72
|
+
def attribute_methods_generated?
|
73
|
+
@attribute_methods_generated ||= false
|
124
74
|
end
|
125
75
|
|
126
|
-
#
|
127
|
-
|
128
|
-
|
76
|
+
# We will define the methods as instance methods, but will call them as singleton
|
77
|
+
# methods. This allows us to use method_defined? to check if the method exists,
|
78
|
+
# which is fast and won't give any false positives from the ancestors (because
|
79
|
+
# there are no ancestors).
|
80
|
+
def generated_external_attribute_methods
|
81
|
+
@generated_external_attribute_methods ||= Module.new { extend self }
|
129
82
|
end
|
130
83
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
@@attribute_method_regexp = /(#{suffixes.join('|')})\z/.freeze
|
136
|
-
end
|
137
|
-
|
138
|
-
# Default to =, ?, _before_type_cast
|
139
|
-
def attribute_method_suffixes
|
140
|
-
@@attribute_method_suffixes ||= []
|
141
|
-
end
|
142
|
-
|
143
|
-
def create_time_zone_conversion_attribute?(name, column)
|
144
|
-
time_zone_aware_attributes && !skip_time_zone_conversion_for_attributes.include?(name.to_sym) && [:datetime, :timestamp].include?(column.type)
|
145
|
-
end
|
146
|
-
|
147
|
-
# Define an attribute reader method. Cope with nil column.
|
148
|
-
def define_read_method(symbol, attr_name, column)
|
149
|
-
cast_code = column.type_cast_code('v') if column
|
150
|
-
access_code = cast_code ? "(v=@attributes['#{attr_name}']) && #{cast_code}" : "@attributes['#{attr_name}']"
|
151
|
-
|
152
|
-
unless attr_name.to_s == self.primary_key.to_s
|
153
|
-
access_code = access_code.insert(0, "missing_attribute('#{attr_name}', caller) unless @attributes.has_key?('#{attr_name}'); ")
|
154
|
-
end
|
155
|
-
|
156
|
-
if cache_attribute?(attr_name)
|
157
|
-
access_code = "@attributes_cache['#{attr_name}'] ||= (#{access_code})"
|
158
|
-
end
|
159
|
-
evaluate_attribute_method attr_name, "def #{symbol}; #{access_code}; end"
|
160
|
-
end
|
161
|
-
|
162
|
-
# Define read method for serialized attribute.
|
163
|
-
def define_read_method_for_serialized_attribute(attr_name)
|
164
|
-
evaluate_attribute_method attr_name, "def #{attr_name}; unserialize_attribute('#{attr_name}'); end"
|
165
|
-
end
|
166
|
-
|
167
|
-
# Defined for all +datetime+ and +timestamp+ attributes when +time_zone_aware_attributes+ are enabled.
|
168
|
-
# This enhanced read method automatically converts the UTC time stored in the database to the time zone stored in Time.zone.
|
169
|
-
def define_read_method_for_time_zone_conversion(attr_name)
|
170
|
-
method_body = <<-EOV
|
171
|
-
def #{attr_name}(reload = false)
|
172
|
-
cached = @attributes_cache['#{attr_name}']
|
173
|
-
return cached if cached && !reload
|
174
|
-
time = read_attribute('#{attr_name}')
|
175
|
-
@attributes_cache['#{attr_name}'] = time.acts_like?(:time) ? time.in_time_zone : time
|
176
|
-
end
|
177
|
-
EOV
|
178
|
-
evaluate_attribute_method attr_name, method_body
|
179
|
-
end
|
180
|
-
|
181
|
-
# Defines a predicate method <tt>attr_name?</tt>.
|
182
|
-
def define_question_method(attr_name)
|
183
|
-
evaluate_attribute_method attr_name, "def #{attr_name}?; query_attribute('#{attr_name}'); end", "#{attr_name}?"
|
184
|
-
end
|
84
|
+
def undefine_attribute_methods
|
85
|
+
super
|
86
|
+
@attribute_methods_generated = false
|
87
|
+
end
|
185
88
|
|
186
|
-
|
187
|
-
|
89
|
+
def instance_method_already_implemented?(method_name)
|
90
|
+
if dangerous_attribute_method?(method_name)
|
91
|
+
raise DangerousAttributeError, "#{method_name} is defined by ActiveRecord"
|
188
92
|
end
|
189
93
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
end
|
197
|
-
write_attribute(:#{attr_name}, value)
|
198
|
-
end
|
199
|
-
EOV
|
200
|
-
evaluate_attribute_method attr_name, method_body, "#{attr_name}="
|
201
|
-
end
|
202
|
-
|
203
|
-
# Defined for all +datetime+ and +timestamp+ attributes when +time_zone_aware_attributes+ are enabled.
|
204
|
-
# This enhanced write method will automatically convert the time passed to it to the zone stored in Time.zone.
|
205
|
-
def define_write_method_for_time_zone_conversion(attr_name)
|
206
|
-
method_body = <<-EOV
|
207
|
-
def #{attr_name}=(time)
|
208
|
-
unless time.acts_like?(:time)
|
209
|
-
time = time.is_a?(String) ? Time.zone.parse(time) : time.to_time rescue time
|
210
|
-
end
|
211
|
-
time = time.in_time_zone rescue nil if time
|
212
|
-
write_attribute(:#{attr_name}, time)
|
213
|
-
end
|
214
|
-
EOV
|
215
|
-
evaluate_attribute_method attr_name, method_body, "#{attr_name}="
|
94
|
+
if superclass == Base
|
95
|
+
super
|
96
|
+
else
|
97
|
+
# If B < A and A defines its own attribute method, then we don't want to overwrite that.
|
98
|
+
defined = method_defined_within?(method_name, superclass, superclass.generated_attribute_methods)
|
99
|
+
defined && !ActiveRecord::Base.method_defined?(method_name) || super
|
216
100
|
end
|
101
|
+
end
|
217
102
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
end
|
103
|
+
# A method name is 'dangerous' if it is already defined by Active Record, but
|
104
|
+
# not by any ancestors. (So 'puts' is not dangerous but 'save' is.)
|
105
|
+
def dangerous_attribute_method?(name)
|
106
|
+
method_defined_within?(name, Base)
|
107
|
+
end
|
224
108
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
logger.warn "Maybe #{attr_name} is not a valid Ruby identifier?"
|
232
|
-
logger.warn err.message
|
233
|
-
end
|
109
|
+
def method_defined_within?(name, klass, sup = klass.superclass)
|
110
|
+
if klass.method_defined?(name) || klass.private_method_defined?(name)
|
111
|
+
if sup.method_defined?(name) || sup.private_method_defined?(name)
|
112
|
+
klass.instance_method(name).owner != sup.instance_method(name).owner
|
113
|
+
else
|
114
|
+
true
|
234
115
|
end
|
116
|
+
else
|
117
|
+
false
|
235
118
|
end
|
236
|
-
|
237
|
-
|
119
|
+
end
|
238
120
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
# ActiveRecord#attributes=. A Milestone class can also ask Milestone#completed? to test that
|
243
|
-
# the completed attribute is not +nil+ or 0.
|
244
|
-
#
|
245
|
-
# It's also possible to instantiate related objects, so a Client class belonging to the clients
|
246
|
-
# table with a +master_id+ foreign key can instantiate master through Client#master.
|
247
|
-
def method_missing(method_id, *args, &block)
|
248
|
-
method_name = method_id.to_s
|
121
|
+
def attribute_method?(attribute)
|
122
|
+
super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, '')))
|
123
|
+
end
|
249
124
|
|
250
|
-
if
|
251
|
-
|
125
|
+
# Returns an array of column names as strings if it's not
|
126
|
+
# an abstract class and table exists.
|
127
|
+
# Otherwise it returns an empty array.
|
128
|
+
def attribute_names
|
129
|
+
@attribute_names ||= if !abstract_class? && table_exists?
|
130
|
+
column_names
|
131
|
+
else
|
132
|
+
[]
|
133
|
+
end
|
252
134
|
end
|
135
|
+
end
|
253
136
|
|
254
|
-
|
255
|
-
|
256
|
-
|
137
|
+
# If we haven't generated any methods yet, generate them, then
|
138
|
+
# see if we've created the method we're looking for.
|
139
|
+
def method_missing(method, *args, &block)
|
140
|
+
unless self.class.attribute_methods_generated?
|
257
141
|
self.class.define_attribute_methods
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
end
|
262
|
-
|
263
|
-
if self.class.primary_key.to_s == method_name
|
264
|
-
id
|
265
|
-
elsif md = self.class.match_attribute_method?(method_name)
|
266
|
-
attribute_name, method_type = md.pre_match, md.to_s
|
267
|
-
if @attributes.include?(attribute_name)
|
268
|
-
__send__("attribute#{method_type}", attribute_name, *args, &block)
|
142
|
+
|
143
|
+
if respond_to_without_attributes?(method)
|
144
|
+
send(method, *args, &block)
|
269
145
|
else
|
270
146
|
super
|
271
147
|
end
|
272
|
-
elsif @attributes.include?(method_name)
|
273
|
-
read_attribute(method_name)
|
274
148
|
else
|
275
149
|
super
|
276
150
|
end
|
277
151
|
end
|
278
152
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
column.type_cast(value)
|
289
|
-
end
|
290
|
-
else
|
291
|
-
value
|
292
|
-
end
|
293
|
-
else
|
294
|
-
nil
|
153
|
+
def attribute_missing(match, *args, &block)
|
154
|
+
if self.class.columns_hash[match.attr_name]
|
155
|
+
ActiveSupport::Deprecation.warn(
|
156
|
+
"The method `#{match.method_name}', matching the attribute `#{match.attr_name}' has " \
|
157
|
+
"dispatched through method_missing. This shouldn't happen, because `#{match.attr_name}' " \
|
158
|
+
"is a column of the table. If this error has happened through normal usage of Active " \
|
159
|
+
"Record (rather than through your own code or external libraries), please report it as " \
|
160
|
+
"a bug."
|
161
|
+
)
|
295
162
|
end
|
163
|
+
|
164
|
+
super
|
296
165
|
end
|
297
166
|
|
298
|
-
def
|
299
|
-
|
167
|
+
def respond_to?(name, include_private = false)
|
168
|
+
self.class.define_attribute_methods unless self.class.attribute_methods_generated?
|
169
|
+
super
|
300
170
|
end
|
301
171
|
|
302
|
-
# Returns true if the attribute is
|
303
|
-
def
|
304
|
-
|
172
|
+
# Returns true if the given attribute is in the attributes hash
|
173
|
+
def has_attribute?(attr_name)
|
174
|
+
@attributes.has_key?(attr_name.to_s)
|
305
175
|
end
|
306
176
|
|
307
|
-
# Returns
|
308
|
-
def
|
309
|
-
|
177
|
+
# Returns an array of names for the attributes available on this object.
|
178
|
+
def attribute_names
|
179
|
+
@attributes.keys
|
180
|
+
end
|
310
181
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
end
|
182
|
+
# Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
|
183
|
+
def attributes
|
184
|
+
attrs = {}
|
185
|
+
attribute_names.each { |name| attrs[name] = read_attribute(name) }
|
186
|
+
attrs
|
317
187
|
end
|
318
|
-
|
319
|
-
|
320
|
-
#
|
321
|
-
#
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
188
|
+
|
189
|
+
# Returns an <tt>#inspect</tt>-like string for the value of the
|
190
|
+
# attribute +attr_name+. String attributes are truncated upto 50
|
191
|
+
# characters, and Date and Time attributes are returned in the
|
192
|
+
# <tt>:db</tt> format. Other attributes return the value of
|
193
|
+
# <tt>#inspect</tt> without modification.
|
194
|
+
#
|
195
|
+
# person = Person.create!(:name => "David Heinemeier Hansson " * 3)
|
196
|
+
#
|
197
|
+
# person.attribute_for_inspect(:name)
|
198
|
+
# # => '"David Heinemeier Hansson David Heinemeier Hansson D..."'
|
199
|
+
#
|
200
|
+
# person.attribute_for_inspect(:created_at)
|
201
|
+
# # => '"2009-01-12 04:48:57"'
|
202
|
+
def attribute_for_inspect(attr_name)
|
203
|
+
value = read_attribute(attr_name)
|
204
|
+
|
205
|
+
if value.is_a?(String) && value.length > 50
|
206
|
+
"#{value[0..50]}...".inspect
|
207
|
+
elsif value.is_a?(Date) || value.is_a?(Time)
|
208
|
+
%("#{value.to_s(:db)}")
|
327
209
|
else
|
328
|
-
|
210
|
+
value.inspect
|
329
211
|
end
|
330
212
|
end
|
331
213
|
|
214
|
+
# Returns true if the specified +attribute+ has been set by the user or by a database load and is neither
|
215
|
+
# nil nor empty? (the latter only applies to objects that respond to empty?, most notably Strings).
|
216
|
+
def attribute_present?(attribute)
|
217
|
+
value = read_attribute(attribute)
|
218
|
+
!value.nil? && !(value.respond_to?(:empty?) && value.empty?)
|
219
|
+
end
|
332
220
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
else
|
337
|
-
column = self.class.columns_hash[attr_name]
|
338
|
-
if column.nil?
|
339
|
-
if Numeric === value || value !~ /[^0-9]/
|
340
|
-
!value.to_i.zero?
|
341
|
-
else
|
342
|
-
return false if ActiveRecord::ConnectionAdapters::Column::FALSE_VALUES.include?(value)
|
343
|
-
!value.blank?
|
344
|
-
end
|
345
|
-
elsif column.number?
|
346
|
-
!value.zero?
|
347
|
-
else
|
348
|
-
!value.blank?
|
349
|
-
end
|
350
|
-
end
|
221
|
+
# Returns the column object for the named attribute.
|
222
|
+
def column_for_attribute(name)
|
223
|
+
self.class.columns_hash[name.to_s]
|
351
224
|
end
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
method_name = method.to_s
|
359
|
-
if super
|
360
|
-
return true
|
361
|
-
elsif !include_private_methods && super(method, true)
|
362
|
-
# If we're here than we haven't found among non-private methods
|
363
|
-
# but found among all methods. Which means that given method is private.
|
364
|
-
return false
|
365
|
-
elsif !self.class.generated_methods?
|
366
|
-
self.class.define_attribute_methods
|
367
|
-
if self.class.generated_methods.include?(method_name)
|
368
|
-
return true
|
369
|
-
end
|
370
|
-
end
|
371
|
-
|
372
|
-
if @attributes.nil?
|
373
|
-
return super
|
374
|
-
elsif @attributes.include?(method_name)
|
375
|
-
return true
|
376
|
-
elsif md = self.class.match_attribute_method?(method_name)
|
377
|
-
return true if @attributes.include?(md.pre_match)
|
225
|
+
|
226
|
+
protected
|
227
|
+
|
228
|
+
def clone_attributes(reader_method = :read_attribute, attributes = {})
|
229
|
+
attribute_names.each do |name|
|
230
|
+
attributes[name] = clone_attribute_value(reader_method, name)
|
378
231
|
end
|
379
|
-
|
232
|
+
attributes
|
380
233
|
end
|
381
234
|
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
# Handle *? for method_missing.
|
389
|
-
def attribute?(attribute_name)
|
390
|
-
query_attribute(attribute_name)
|
391
|
-
end
|
235
|
+
def clone_attribute_value(reader_method, attribute_name)
|
236
|
+
value = send(reader_method, attribute_name)
|
237
|
+
value.duplicable? ? value.clone : value
|
238
|
+
rescue TypeError, NoMethodError
|
239
|
+
value
|
240
|
+
end
|
392
241
|
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
242
|
+
# Returns a copy of the attributes hash where all the values have been safely quoted for use in
|
243
|
+
# an Arel insert/update method.
|
244
|
+
def arel_attributes_values(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys)
|
245
|
+
attrs = {}
|
246
|
+
klass = self.class
|
247
|
+
arel_table = klass.arel_table
|
248
|
+
|
249
|
+
attribute_names.each do |name|
|
250
|
+
if (column = column_for_attribute(name)) && (include_primary_key || !column.primary)
|
397
251
|
|
398
|
-
|
399
|
-
|
400
|
-
|
252
|
+
if include_readonly_attributes || !self.class.readonly_attributes.include?(name)
|
253
|
+
|
254
|
+
value = if klass.serialized_attributes.include?(name)
|
255
|
+
@attributes[name].serialized_value
|
256
|
+
else
|
257
|
+
# FIXME: we need @attributes to be used consistently.
|
258
|
+
# If the values stored in @attributes were already type
|
259
|
+
# casted, this code could be simplified
|
260
|
+
read_attribute(name)
|
261
|
+
end
|
262
|
+
|
263
|
+
attrs[arel_table[name]] = value
|
264
|
+
end
|
265
|
+
end
|
401
266
|
end
|
267
|
+
|
268
|
+
attrs
|
269
|
+
end
|
270
|
+
|
271
|
+
def attribute_method?(attr_name)
|
272
|
+
attr_name == 'id' || (defined?(@attributes) && @attributes.include?(attr_name))
|
273
|
+
end
|
402
274
|
end
|
403
275
|
end
|