activerecord 5.0.6 → 6.0.1
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 +5 -5
- data/CHANGELOG.md +638 -2023
- data/MIT-LICENSE +3 -1
- data/README.rdoc +8 -6
- data/examples/performance.rb +31 -29
- data/examples/simple.rb +5 -3
- data/lib/active_record/aggregations.rb +249 -246
- data/lib/active_record/association_relation.rb +24 -13
- data/lib/active_record/associations/alias_tracker.rb +24 -33
- data/lib/active_record/associations/association.rb +119 -56
- data/lib/active_record/associations/association_scope.rb +94 -94
- data/lib/active_record/associations/belongs_to_association.rb +58 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
- data/lib/active_record/associations/builder/association.rb +18 -25
- data/lib/active_record/associations/builder/belongs_to.rb +43 -54
- data/lib/active_record/associations/builder/collection_association.rb +7 -18
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -61
- data/lib/active_record/associations/builder/has_many.rb +4 -0
- data/lib/active_record/associations/builder/has_one.rb +37 -1
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +80 -252
- data/lib/active_record/associations/collection_proxy.rb +158 -121
- data/lib/active_record/associations/foreign_association.rb +9 -0
- data/lib/active_record/associations/has_many_association.rb +23 -29
- data/lib/active_record/associations/has_many_through_association.rb +58 -44
- data/lib/active_record/associations/has_one_association.rb +59 -54
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +38 -90
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
- data/lib/active_record/associations/join_dependency.rb +134 -176
- data/lib/active_record/associations/preloader/association.rb +84 -125
- data/lib/active_record/associations/preloader/through_association.rb +82 -75
- data/lib/active_record/associations/preloader.rb +90 -102
- data/lib/active_record/associations/singular_association.rb +12 -45
- data/lib/active_record/associations/through_association.rb +26 -14
- data/lib/active_record/associations.rb +1603 -1592
- data/lib/active_record/attribute_assignment.rb +54 -60
- data/lib/active_record/attribute_decorators.rb +38 -15
- data/lib/active_record/attribute_methods/before_type_cast.rb +12 -7
- data/lib/active_record/attribute_methods/dirty.rb +179 -109
- data/lib/active_record/attribute_methods/primary_key.rb +86 -91
- data/lib/active_record/attribute_methods/query.rb +4 -3
- data/lib/active_record/attribute_methods/read.rb +21 -49
- data/lib/active_record/attribute_methods/serialization.rb +30 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -64
- data/lib/active_record/attribute_methods/write.rb +35 -33
- data/lib/active_record/attribute_methods.rb +66 -106
- data/lib/active_record/attributes.rb +38 -24
- data/lib/active_record/autosave_association.rb +53 -32
- data/lib/active_record/base.rb +27 -24
- data/lib/active_record/callbacks.rb +63 -33
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +11 -11
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +553 -321
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +213 -94
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -28
- data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -27
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -126
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +369 -199
- data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
- data/lib/active_record/connection_adapters/abstract_adapter.rb +363 -202
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +405 -551
- data/lib/active_record/connection_adapters/column.rb +41 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +172 -138
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
- data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +143 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -22
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +50 -45
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +49 -30
- data/lib/active_record/connection_adapters/postgresql/column.rb +22 -7
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +60 -54
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -10
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -17
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
- data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +31 -9
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -30
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -4
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +35 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +380 -300
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
- data/lib/active_record/connection_adapters/postgresql/utils.rb +10 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +382 -275
- data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +74 -19
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +254 -262
- data/lib/active_record/connection_adapters/statement_pool.rb +9 -7
- data/lib/active_record/connection_handling.rb +159 -40
- data/lib/active_record/core.rb +202 -162
- data/lib/active_record/counter_cache.rb +57 -28
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +79 -0
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -86
- data/lib/active_record/enum.rb +60 -23
- data/lib/active_record/errors.rb +114 -18
- data/lib/active_record/explain.rb +4 -3
- data/lib/active_record/explain_registry.rb +3 -1
- data/lib/active_record/explain_subscriber.rb +9 -4
- data/lib/active_record/fixture_set/file.rb +13 -8
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +153 -0
- data/lib/active_record/fixture_set/table_rows.rb +47 -0
- data/lib/active_record/fixtures.rb +195 -502
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +151 -97
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +116 -25
- data/lib/active_record/internal_metadata.rb +15 -18
- data/lib/active_record/legacy_yaml_adapter.rb +4 -2
- data/lib/active_record/locking/optimistic.rb +78 -87
- data/lib/active_record/locking/pessimistic.rb +18 -6
- data/lib/active_record/log_subscriber.rb +48 -29
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/migration/command_recorder.rb +143 -97
- data/lib/active_record/migration/compatibility.rb +174 -56
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/migration.rb +367 -300
- data/lib/active_record/model_schema.rb +145 -139
- data/lib/active_record/nested_attributes.rb +214 -201
- data/lib/active_record/no_touching.rb +10 -1
- data/lib/active_record/null_relation.rb +13 -34
- data/lib/active_record/persistence.rb +442 -72
- data/lib/active_record/query_cache.rb +15 -14
- data/lib/active_record/querying.rb +36 -23
- data/lib/active_record/railtie.rb +128 -36
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +34 -33
- data/lib/active_record/railties/databases.rake +309 -177
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +211 -249
- data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
- data/lib/active_record/relation/batches.rb +99 -52
- data/lib/active_record/relation/calculations.rb +211 -172
- data/lib/active_record/relation/delegation.rb +67 -65
- data/lib/active_record/relation/finder_methods.rb +208 -247
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +78 -61
- data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/predicate_builder.rb +86 -104
- data/lib/active_record/relation/query_attribute.rb +33 -2
- data/lib/active_record/relation/query_methods.rb +458 -329
- data/lib/active_record/relation/record_fetch_warning.rb +5 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -7
- data/lib/active_record/relation/where_clause.rb +111 -95
- data/lib/active_record/relation/where_clause_factory.rb +6 -11
- data/lib/active_record/relation.rb +429 -318
- data/lib/active_record/result.rb +69 -39
- data/lib/active_record/runtime_registry.rb +5 -3
- data/lib/active_record/sanitization.rb +83 -99
- data/lib/active_record/schema.rb +7 -14
- data/lib/active_record/schema_dumper.rb +71 -69
- data/lib/active_record/schema_migration.rb +15 -5
- data/lib/active_record/scoping/default.rb +93 -95
- data/lib/active_record/scoping/named.rb +45 -25
- data/lib/active_record/scoping.rb +20 -19
- data/lib/active_record/secure_token.rb +4 -2
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +63 -28
- data/lib/active_record/store.rb +121 -41
- data/lib/active_record/suppressor.rb +4 -1
- data/lib/active_record/table_metadata.rb +26 -20
- data/lib/active_record/tasks/database_tasks.rb +276 -85
- data/lib/active_record/tasks/mysql_database_tasks.rb +54 -90
- data/lib/active_record/tasks/postgresql_database_tasks.rb +78 -47
- data/lib/active_record/tasks/sqlite_database_tasks.rb +34 -16
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +224 -0
- data/lib/active_record/timestamp.rb +70 -35
- data/lib/active_record/touch_later.rb +7 -4
- data/lib/active_record/transactions.rb +133 -149
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +44 -45
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +15 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +16 -8
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +2 -1
- data/lib/active_record/type/type_map.rb +13 -15
- data/lib/active_record/type/unsigned_integer.rb +17 -0
- data/lib/active_record/type.rb +23 -17
- data/lib/active_record/type_caster/connection.rb +17 -12
- data/lib/active_record/type_caster/map.rb +5 -4
- data/lib/active_record/type_caster.rb +4 -2
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +3 -1
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +4 -2
- data/lib/active_record/validations/uniqueness.rb +29 -42
- data/lib/active_record/validations.rb +7 -4
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +36 -22
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +45 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/nodes.rb +68 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +257 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/depth_first.rb +204 -0
- data/lib/arel/visitors/dot.rb +297 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +157 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +159 -0
- data/lib/arel/visitors/oracle12.rb +66 -0
- data/lib/arel/visitors/postgresql.rb +110 -0
- data/lib/arel/visitors/sqlite.rb +39 -0
- data/lib/arel/visitors/to_sql.rb +889 -0
- data/lib/arel/visitors/visitor.rb +46 -0
- data/lib/arel/visitors/where_sql.rb +23 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +58 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
- data/lib/rails/generators/active_record/migration.rb +17 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -29
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +133 -50
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -20
- data/lib/active_record/attribute/user_provided_default.rb +0 -28
- data/lib/active_record/attribute.rb +0 -213
- data/lib/active_record/attribute_mutation_tracker.rb +0 -70
- data/lib/active_record/attribute_set/builder.rb +0 -130
- data/lib/active_record/attribute_set.rb +0 -110
- data/lib/active_record/collection_cache_key.rb +0 -50
- data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
- data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "stringio"
|
2
4
|
|
3
5
|
module ActiveRecord
|
4
6
|
# = Active Record Schema Dumper
|
@@ -11,14 +13,19 @@ module ActiveRecord
|
|
11
13
|
##
|
12
14
|
# :singleton-method:
|
13
15
|
# A list of tables which should not be dumped to the schema.
|
14
|
-
# Acceptable values are strings as well as regexp.
|
15
|
-
#
|
16
|
-
cattr_accessor :ignore_tables
|
17
|
-
|
16
|
+
# Acceptable values are strings as well as regexp if ActiveRecord::Base.schema_format == :ruby.
|
17
|
+
# Only strings are accepted if ActiveRecord::Base.schema_format == :sql.
|
18
|
+
cattr_accessor :ignore_tables, default: []
|
19
|
+
|
20
|
+
##
|
21
|
+
# :singleton-method:
|
22
|
+
# Specify a custom regular expression matching foreign keys which name
|
23
|
+
# should not be dumped to db/schema.rb.
|
24
|
+
cattr_accessor :fk_ignore_pattern, default: /^fk_rails_[0-9a-f]{10}$/
|
18
25
|
|
19
26
|
class << self
|
20
|
-
def dump(connection=ActiveRecord::Base.connection, stream=STDOUT, config = ActiveRecord::Base)
|
21
|
-
|
27
|
+
def dump(connection = ActiveRecord::Base.connection, stream = STDOUT, config = ActiveRecord::Base)
|
28
|
+
connection.create_schema_dumper(generate_options(config)).dump(stream)
|
22
29
|
stream
|
23
30
|
end
|
24
31
|
|
@@ -40,26 +47,36 @@ module ActiveRecord
|
|
40
47
|
end
|
41
48
|
|
42
49
|
private
|
50
|
+
attr_accessor :table_name
|
43
51
|
|
44
52
|
def initialize(connection, options = {})
|
45
53
|
@connection = connection
|
46
|
-
@version =
|
54
|
+
@version = connection.migration_context.current_version rescue nil
|
47
55
|
@options = options
|
48
56
|
end
|
49
57
|
|
50
|
-
|
51
|
-
|
58
|
+
# turns 20170404131909 into "2017_04_04_131909"
|
59
|
+
def formatted_version
|
60
|
+
stringified = @version.to_s
|
61
|
+
return stringified unless stringified.length == 14
|
62
|
+
stringified.insert(4, "_").insert(7, "_").insert(10, "_")
|
63
|
+
end
|
64
|
+
|
65
|
+
def define_params
|
66
|
+
@version ? "version: #{formatted_version}" : ""
|
67
|
+
end
|
52
68
|
|
69
|
+
def header(stream)
|
53
70
|
stream.puts <<HEADER
|
54
71
|
# This file is auto-generated from the current state of the database. Instead
|
55
72
|
# of editing this file, please use the migrations feature of Active Record to
|
56
73
|
# incrementally modify your database, and then regenerate this schema definition.
|
57
74
|
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
# from scratch.
|
62
|
-
#
|
75
|
+
# This file is the source Rails uses to define your schema when running `rails
|
76
|
+
# db:schema:load`. When creating a new database, `rails db:schema:load` tends to
|
77
|
+
# be faster and is potentially less error prone than running all of your
|
78
|
+
# migrations from scratch. Old migrations may fail to apply correctly if those
|
79
|
+
# migrations use external dependencies or application code.
|
63
80
|
#
|
64
81
|
# It's strongly recommended that you check this file into your version control system.
|
65
82
|
|
@@ -72,20 +89,12 @@ HEADER
|
|
72
89
|
stream.puts "end"
|
73
90
|
end
|
74
91
|
|
92
|
+
# extensions are only supported by PostgreSQL
|
75
93
|
def extensions(stream)
|
76
|
-
return unless @connection.supports_extensions?
|
77
|
-
extensions = @connection.extensions
|
78
|
-
if extensions.any?
|
79
|
-
stream.puts " # These are extensions that must be enabled in order to support this database"
|
80
|
-
extensions.each do |extension|
|
81
|
-
stream.puts " enable_extension #{extension.inspect}"
|
82
|
-
end
|
83
|
-
stream.puts
|
84
|
-
end
|
85
94
|
end
|
86
95
|
|
87
96
|
def tables(stream)
|
88
|
-
sorted_tables = @connection.
|
97
|
+
sorted_tables = @connection.tables.sort
|
89
98
|
|
90
99
|
sorted_tables.each do |table_name|
|
91
100
|
table(table_name, stream) unless ignored?(table_name)
|
@@ -102,6 +111,8 @@ HEADER
|
|
102
111
|
def table(table, stream)
|
103
112
|
columns = @connection.columns(table)
|
104
113
|
begin
|
114
|
+
self.table_name = table
|
115
|
+
|
105
116
|
tbl = StringIO.new
|
106
117
|
|
107
118
|
# first dump primary key column
|
@@ -111,60 +122,36 @@ HEADER
|
|
111
122
|
|
112
123
|
case pk
|
113
124
|
when String
|
114
|
-
tbl.print ", primary_key: #{pk.inspect}" unless pk ==
|
125
|
+
tbl.print ", primary_key: #{pk.inspect}" unless pk == "id"
|
115
126
|
pkcol = columns.detect { |c| c.name == pk }
|
116
|
-
pkcolspec =
|
127
|
+
pkcolspec = column_spec_for_primary_key(pkcol)
|
117
128
|
if pkcolspec.present?
|
118
|
-
|
119
|
-
tbl.print ", #{key}: #{value}"
|
120
|
-
end
|
129
|
+
tbl.print ", #{format_colspec(pkcolspec)}"
|
121
130
|
end
|
122
131
|
when Array
|
123
132
|
tbl.print ", primary_key: #{pk.inspect}"
|
124
133
|
else
|
125
134
|
tbl.print ", id: false"
|
126
135
|
end
|
127
|
-
tbl.print ", force: :cascade"
|
128
136
|
|
129
137
|
table_options = @connection.table_options(table)
|
130
138
|
if table_options.present?
|
131
139
|
tbl.print ", #{format_options(table_options)}"
|
132
140
|
end
|
133
141
|
|
134
|
-
tbl.puts " do |t|"
|
142
|
+
tbl.puts ", force: :cascade do |t|"
|
135
143
|
|
136
144
|
# then dump all non-primary key columns
|
137
|
-
|
145
|
+
columns.each do |column|
|
138
146
|
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
|
139
147
|
next if column.name == pk
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
lengths = keys.map { |key|
|
148
|
-
column_specs.map { |spec|
|
149
|
-
spec[key] ? spec[key].length + 2 : 0
|
150
|
-
}.max
|
151
|
-
}
|
152
|
-
|
153
|
-
# the string we're going to sprintf our values against, with standardized column widths
|
154
|
-
format_string = lengths.map{ |len| "%-#{len}s" }
|
155
|
-
|
156
|
-
# find the max length for the 'type' column, which is special
|
157
|
-
type_length = column_specs.map{ |column| column[:type].length }.max
|
158
|
-
|
159
|
-
# add column type definition to our format string
|
160
|
-
format_string.unshift " t.%-#{type_length}s "
|
161
|
-
|
162
|
-
format_string *= ''
|
163
|
-
|
164
|
-
column_specs.each do |colspec|
|
165
|
-
values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len }
|
166
|
-
values.unshift colspec[:type]
|
167
|
-
tbl.print((format_string % values).gsub(/,\s*$/, ''))
|
148
|
+
type, colspec = column_spec(column)
|
149
|
+
if type.is_a?(Symbol)
|
150
|
+
tbl.print " t.#{type} #{column.name.inspect}"
|
151
|
+
else
|
152
|
+
tbl.print " t.column #{column.name.inspect}, #{type.inspect}"
|
153
|
+
end
|
154
|
+
tbl.print ", #{format_colspec(colspec)}" if colspec.present?
|
168
155
|
tbl.puts
|
169
156
|
end
|
170
157
|
|
@@ -179,9 +166,9 @@ HEADER
|
|
179
166
|
stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
|
180
167
|
stream.puts "# #{e.message}"
|
181
168
|
stream.puts
|
169
|
+
ensure
|
170
|
+
self.table_name = nil
|
182
171
|
end
|
183
|
-
|
184
|
-
stream
|
185
172
|
end
|
186
173
|
|
187
174
|
# Keep it for indexing materialized views
|
@@ -189,7 +176,7 @@ HEADER
|
|
189
176
|
if (indexes = @connection.indexes(table)).any?
|
190
177
|
add_index_statements = indexes.map do |index|
|
191
178
|
table_name = remove_prefix_and_suffix(index.table).inspect
|
192
|
-
" add_index #{([table_name]+index_parts(index)).join(', ')}"
|
179
|
+
" add_index #{([table_name] + index_parts(index)).join(', ')}"
|
193
180
|
end
|
194
181
|
|
195
182
|
stream.puts add_index_statements.sort.join("\n")
|
@@ -212,10 +199,11 @@ HEADER
|
|
212
199
|
"name: #{index.name.inspect}",
|
213
200
|
]
|
214
201
|
index_parts << "unique: true" if index.unique
|
215
|
-
index_parts << "length:
|
216
|
-
index_parts << "order:
|
202
|
+
index_parts << "length: #{format_index_parts(index.lengths)}" if index.lengths.present?
|
203
|
+
index_parts << "order: #{format_index_parts(index.orders)}" if index.orders.present?
|
204
|
+
index_parts << "opclass: #{format_index_parts(index.opclasses)}" if index.opclasses.present?
|
217
205
|
index_parts << "where: #{index.where.inspect}" if index.where
|
218
|
-
index_parts << "using: #{index.using.inspect}" if index
|
206
|
+
index_parts << "using: #{index.using.inspect}" if !@connection.default_index_type?(index)
|
219
207
|
index_parts << "type: #{index.type.inspect}" if index.type
|
220
208
|
index_parts << "comment: #{index.comment.inspect}" if index.comment
|
221
209
|
index_parts
|
@@ -237,7 +225,7 @@ HEADER
|
|
237
225
|
parts << "primary_key: #{foreign_key.primary_key.inspect}"
|
238
226
|
end
|
239
227
|
|
240
|
-
if foreign_key.
|
228
|
+
if foreign_key.export_name_on_schema_dump?
|
241
229
|
parts << "name: #{foreign_key.name.inspect}"
|
242
230
|
end
|
243
231
|
|
@@ -251,12 +239,26 @@ HEADER
|
|
251
239
|
end
|
252
240
|
end
|
253
241
|
|
242
|
+
def format_colspec(colspec)
|
243
|
+
colspec.map { |key, value| "#{key}: #{value}" }.join(", ")
|
244
|
+
end
|
245
|
+
|
254
246
|
def format_options(options)
|
255
247
|
options.map { |key, value| "#{key}: #{value.inspect}" }.join(", ")
|
256
248
|
end
|
257
249
|
|
250
|
+
def format_index_parts(options)
|
251
|
+
if options.is_a?(Hash)
|
252
|
+
"{ #{format_options(options)} }"
|
253
|
+
else
|
254
|
+
options.inspect
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
258
|
def remove_prefix_and_suffix(table)
|
259
|
-
|
259
|
+
prefix = Regexp.escape(@options[:table_name_prefix].to_s)
|
260
|
+
suffix = Regexp.escape(@options[:table_name_suffix].to_s)
|
261
|
+
table.sub(/\A#{prefix}(.+)#{suffix}\z/, "\\1")
|
260
262
|
end
|
261
263
|
|
262
264
|
def ignored?(table_name)
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_record/scoping/default"
|
4
|
+
require "active_record/scoping/named"
|
3
5
|
|
4
6
|
module ActiveRecord
|
5
7
|
# This class is used to create a table that keeps track of which migrations
|
@@ -8,16 +10,20 @@ module ActiveRecord
|
|
8
10
|
# to be executed the next time.
|
9
11
|
class SchemaMigration < ActiveRecord::Base # :nodoc:
|
10
12
|
class << self
|
13
|
+
def _internal?
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
11
17
|
def primary_key
|
12
18
|
"version"
|
13
19
|
end
|
14
20
|
|
15
21
|
def table_name
|
16
|
-
"#{table_name_prefix}#{
|
22
|
+
"#{table_name_prefix}#{schema_migrations_table_name}#{table_name_suffix}"
|
17
23
|
end
|
18
24
|
|
19
25
|
def table_exists?
|
20
|
-
|
26
|
+
connection.table_exists?(table_name)
|
21
27
|
end
|
22
28
|
|
23
29
|
def create_table
|
@@ -39,7 +45,11 @@ module ActiveRecord
|
|
39
45
|
end
|
40
46
|
|
41
47
|
def normalized_versions
|
42
|
-
|
48
|
+
all_versions.map { |v| normalize_migration_number v }
|
49
|
+
end
|
50
|
+
|
51
|
+
def all_versions
|
52
|
+
order(:version).pluck(:version)
|
43
53
|
end
|
44
54
|
end
|
45
55
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Scoping
|
3
5
|
module Default
|
@@ -5,11 +7,8 @@ module ActiveRecord
|
|
5
7
|
|
6
8
|
included do
|
7
9
|
# Stores the default scope for the class.
|
8
|
-
class_attribute :default_scopes, instance_writer: false, instance_predicate: false
|
9
|
-
class_attribute :default_scope_override, instance_writer: false, instance_predicate: false
|
10
|
-
|
11
|
-
self.default_scopes = []
|
12
|
-
self.default_scope_override = nil
|
10
|
+
class_attribute :default_scopes, instance_writer: false, instance_predicate: false, default: []
|
11
|
+
class_attribute :default_scope_override, instance_writer: false, instance_predicate: false, default: nil
|
13
12
|
end
|
14
13
|
|
15
14
|
module ClassMethods
|
@@ -44,109 +43,108 @@ module ActiveRecord
|
|
44
43
|
self.current_scope = nil
|
45
44
|
end
|
46
45
|
|
47
|
-
|
46
|
+
private
|
47
|
+
|
48
|
+
# Use this macro in your model to set a default scope for all operations on
|
49
|
+
# the model.
|
50
|
+
#
|
51
|
+
# class Article < ActiveRecord::Base
|
52
|
+
# default_scope { where(published: true) }
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# Article.all # => SELECT * FROM articles WHERE published = true
|
56
|
+
#
|
57
|
+
# The #default_scope is also applied while creating/building a record.
|
58
|
+
# It is not applied while updating a record.
|
59
|
+
#
|
60
|
+
# Article.new.published # => true
|
61
|
+
# Article.create.published # => true
|
62
|
+
#
|
63
|
+
# (You can also pass any object which responds to +call+ to the
|
64
|
+
# +default_scope+ macro, and it will be called when building the
|
65
|
+
# default scope.)
|
66
|
+
#
|
67
|
+
# If you use multiple #default_scope declarations in your model then
|
68
|
+
# they will be merged together:
|
69
|
+
#
|
70
|
+
# class Article < ActiveRecord::Base
|
71
|
+
# default_scope { where(published: true) }
|
72
|
+
# default_scope { where(rating: 'G') }
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'
|
76
|
+
#
|
77
|
+
# This is also the case with inheritance and module includes where the
|
78
|
+
# parent or module defines a #default_scope and the child or including
|
79
|
+
# class defines a second one.
|
80
|
+
#
|
81
|
+
# If you need to do more complex things with a default scope, you can
|
82
|
+
# alternatively define it as a class method:
|
83
|
+
#
|
84
|
+
# class Article < ActiveRecord::Base
|
85
|
+
# def self.default_scope
|
86
|
+
# # Should return a scope, you can call 'super' here etc.
|
87
|
+
# end
|
88
|
+
# end
|
89
|
+
def default_scope(scope = nil, &block) # :doc:
|
90
|
+
scope = block if block_given?
|
91
|
+
|
92
|
+
if scope.is_a?(Relation) || !scope.respond_to?(:call)
|
93
|
+
raise ArgumentError,
|
94
|
+
"Support for calling #default_scope without a block is removed. For example instead " \
|
95
|
+
"of `default_scope where(color: 'red')`, please use " \
|
96
|
+
"`default_scope { where(color: 'red') }`. (Alternatively you can just redefine " \
|
97
|
+
"self.default_scope.)"
|
98
|
+
end
|
48
99
|
|
49
|
-
|
50
|
-
# the model.
|
51
|
-
#
|
52
|
-
# class Article < ActiveRecord::Base
|
53
|
-
# default_scope { where(published: true) }
|
54
|
-
# end
|
55
|
-
#
|
56
|
-
# Article.all # => SELECT * FROM articles WHERE published = true
|
57
|
-
#
|
58
|
-
# The #default_scope is also applied while creating/building a record.
|
59
|
-
# It is not applied while updating a record.
|
60
|
-
#
|
61
|
-
# Article.new.published # => true
|
62
|
-
# Article.create.published # => true
|
63
|
-
#
|
64
|
-
# (You can also pass any object which responds to +call+ to the
|
65
|
-
# +default_scope+ macro, and it will be called when building the
|
66
|
-
# default scope.)
|
67
|
-
#
|
68
|
-
# If you use multiple #default_scope declarations in your model then
|
69
|
-
# they will be merged together:
|
70
|
-
#
|
71
|
-
# class Article < ActiveRecord::Base
|
72
|
-
# default_scope { where(published: true) }
|
73
|
-
# default_scope { where(rating: 'G') }
|
74
|
-
# end
|
75
|
-
#
|
76
|
-
# Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'
|
77
|
-
#
|
78
|
-
# This is also the case with inheritance and module includes where the
|
79
|
-
# parent or module defines a #default_scope and the child or including
|
80
|
-
# class defines a second one.
|
81
|
-
#
|
82
|
-
# If you need to do more complex things with a default scope, you can
|
83
|
-
# alternatively define it as a class method:
|
84
|
-
#
|
85
|
-
# class Article < ActiveRecord::Base
|
86
|
-
# def self.default_scope
|
87
|
-
# # Should return a scope, you can call 'super' here etc.
|
88
|
-
# end
|
89
|
-
# end
|
90
|
-
def default_scope(scope = nil)
|
91
|
-
scope = Proc.new if block_given?
|
92
|
-
|
93
|
-
if scope.is_a?(Relation) || !scope.respond_to?(:call)
|
94
|
-
raise ArgumentError,
|
95
|
-
"Support for calling #default_scope without a block is removed. For example instead " \
|
96
|
-
"of `default_scope where(color: 'red')`, please use " \
|
97
|
-
"`default_scope { where(color: 'red') }`. (Alternatively you can just redefine " \
|
98
|
-
"self.default_scope.)"
|
100
|
+
self.default_scopes += [scope]
|
99
101
|
end
|
100
102
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
def build_default_scope(base_rel = nil) # :nodoc:
|
105
|
-
return if abstract_class?
|
103
|
+
def build_default_scope(relation = relation())
|
104
|
+
return if abstract_class?
|
106
105
|
|
107
|
-
|
108
|
-
|
109
|
-
|
106
|
+
if default_scope_override.nil?
|
107
|
+
self.default_scope_override = !Base.is_a?(method(:default_scope).owner)
|
108
|
+
end
|
110
109
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
110
|
+
if default_scope_override
|
111
|
+
# The user has defined their own default scope method, so call that
|
112
|
+
evaluate_default_scope do
|
113
|
+
if scope = default_scope
|
114
|
+
relation.merge!(scope)
|
115
|
+
end
|
116
116
|
end
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
default_scope.merge(base_rel.instance_exec(&scope))
|
117
|
+
elsif default_scopes.any?
|
118
|
+
evaluate_default_scope do
|
119
|
+
default_scopes.inject(relation) do |default_scope, scope|
|
120
|
+
scope = scope.respond_to?(:to_proc) ? scope : scope.method(:call)
|
121
|
+
default_scope.instance_exec(&scope) || default_scope
|
122
|
+
end
|
124
123
|
end
|
125
124
|
end
|
126
125
|
end
|
127
|
-
end
|
128
126
|
|
129
|
-
|
130
|
-
|
131
|
-
|
127
|
+
def ignore_default_scope?
|
128
|
+
ScopeRegistry.value_for(:ignore_default_scope, base_class)
|
129
|
+
end
|
132
130
|
|
133
|
-
|
134
|
-
|
135
|
-
|
131
|
+
def ignore_default_scope=(ignore)
|
132
|
+
ScopeRegistry.set_value_for(:ignore_default_scope, base_class, ignore)
|
133
|
+
end
|
136
134
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
135
|
+
# The ignore_default_scope flag is used to prevent an infinite recursion
|
136
|
+
# situation where a default scope references a scope which has a default
|
137
|
+
# scope which references a scope...
|
138
|
+
def evaluate_default_scope
|
139
|
+
return if ignore_default_scope?
|
140
|
+
|
141
|
+
begin
|
142
|
+
self.ignore_default_scope = true
|
143
|
+
yield
|
144
|
+
ensure
|
145
|
+
self.ignore_default_scope = false
|
146
|
+
end
|
148
147
|
end
|
149
|
-
end
|
150
148
|
end
|
151
149
|
end
|
152
150
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/array"
|
4
|
+
require "active_support/core_ext/hash/except"
|
5
|
+
require "active_support/core_ext/kernel/singleton_class"
|
4
6
|
|
5
7
|
module ActiveRecord
|
6
8
|
# = Active Record \Named \Scopes
|
@@ -22,17 +24,29 @@ module ActiveRecord
|
|
22
24
|
# You can define a scope that applies to all finders using
|
23
25
|
# {default_scope}[rdoc-ref:Scoping::Default::ClassMethods#default_scope].
|
24
26
|
def all
|
25
|
-
|
26
|
-
|
27
|
+
scope = current_scope
|
28
|
+
|
29
|
+
if scope
|
30
|
+
if scope._deprecated_scope_source
|
31
|
+
ActiveSupport::Deprecation.warn(<<~MSG.squish)
|
32
|
+
Class level methods will no longer inherit scoping from `#{scope._deprecated_scope_source}`
|
33
|
+
in Rails 6.1. To continue using the scoped relation, pass it into the block directly.
|
34
|
+
To instead access the full set of models, as Rails 6.1 will, use `#{name}.unscoped`.
|
35
|
+
MSG
|
36
|
+
end
|
37
|
+
|
38
|
+
if self == scope.klass
|
39
|
+
scope.clone
|
40
|
+
else
|
41
|
+
relation.merge!(scope)
|
42
|
+
end
|
27
43
|
else
|
28
44
|
default_scoped
|
29
45
|
end
|
30
46
|
end
|
31
47
|
|
32
48
|
def scope_for_association(scope = relation) # :nodoc:
|
33
|
-
|
34
|
-
|
35
|
-
if current_scope && current_scope.empty_scope?
|
49
|
+
if current_scope&.empty_scope?
|
36
50
|
scope
|
37
51
|
else
|
38
52
|
default_scoped(scope)
|
@@ -44,7 +58,7 @@ module ActiveRecord
|
|
44
58
|
end
|
45
59
|
|
46
60
|
def default_extensions # :nodoc:
|
47
|
-
if scope =
|
61
|
+
if scope = scope_for_association || build_default_scope
|
48
62
|
scope.extensions
|
49
63
|
else
|
50
64
|
[]
|
@@ -54,7 +68,7 @@ module ActiveRecord
|
|
54
68
|
# Adds a class method for retrieving and querying objects.
|
55
69
|
# The method is intended to return an ActiveRecord::Relation
|
56
70
|
# object, which is composable with other scopes.
|
57
|
-
# If it returns nil or false
|
71
|
+
# If it returns +nil+ or +false+, an
|
58
72
|
# {all}[rdoc-ref:Scoping::Named::ClassMethods#all] scope is returned instead.
|
59
73
|
#
|
60
74
|
# A \scope represents a narrowing of a database query, such as
|
@@ -154,7 +168,7 @@ module ActiveRecord
|
|
154
168
|
# Article.featured.titles
|
155
169
|
def scope(name, body, &block)
|
156
170
|
unless body.respond_to?(:call)
|
157
|
-
raise ArgumentError,
|
171
|
+
raise ArgumentError, "The scope body needs to be callable."
|
158
172
|
end
|
159
173
|
|
160
174
|
if dangerous_class_method?(name)
|
@@ -163,34 +177,40 @@ module ActiveRecord
|
|
163
177
|
"a class method with the same name."
|
164
178
|
end
|
165
179
|
|
180
|
+
if method_defined_within?(name, Relation)
|
181
|
+
raise ArgumentError, "You tried to define a scope named \"#{name}\" " \
|
182
|
+
"on the model \"#{self.name}\", but ActiveRecord::Relation already defined " \
|
183
|
+
"an instance method with the same name."
|
184
|
+
end
|
185
|
+
|
166
186
|
valid_scope_name?(name)
|
167
187
|
extension = Module.new(&block) if block
|
168
188
|
|
169
189
|
if body.respond_to?(:to_proc)
|
170
|
-
singleton_class.
|
171
|
-
scope = all.
|
190
|
+
singleton_class.define_method(name) do |*args|
|
191
|
+
scope = all._exec_scope(name, *args, &body)
|
172
192
|
scope = scope.extending(extension) if extension
|
173
|
-
|
174
|
-
scope || all
|
193
|
+
scope
|
175
194
|
end
|
176
195
|
else
|
177
|
-
singleton_class.
|
178
|
-
scope =
|
196
|
+
singleton_class.define_method(name) do |*args|
|
197
|
+
scope = body.call(*args) || all
|
179
198
|
scope = scope.extending(extension) if extension
|
180
|
-
|
181
|
-
scope || all
|
199
|
+
scope
|
182
200
|
end
|
183
201
|
end
|
202
|
+
|
203
|
+
generate_relation_method(name)
|
184
204
|
end
|
185
205
|
|
186
|
-
|
206
|
+
private
|
187
207
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
208
|
+
def valid_scope_name?(name)
|
209
|
+
if respond_to?(name, true) && logger
|
210
|
+
logger.warn "Creating scope :#{name}. " \
|
211
|
+
"Overwriting existing method #{self.name}.#{name}."
|
212
|
+
end
|
192
213
|
end
|
193
|
-
end
|
194
214
|
end
|
195
215
|
end
|
196
216
|
end
|