activerecord 5.0.7.2 → 6.0.6.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 +4 -4
- data/CHANGELOG.md +844 -1944
- data/MIT-LICENSE +3 -1
- data/README.rdoc +9 -7
- data/examples/performance.rb +31 -29
- data/examples/simple.rb +5 -3
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +249 -247
- data/lib/active_record/association_relation.rb +18 -14
- data/lib/active_record/associations/alias_tracker.rb +24 -34
- data/lib/active_record/associations/association.rb +113 -55
- data/lib/active_record/associations/association_scope.rb +102 -96
- 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 +41 -62
- 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 +93 -254
- data/lib/active_record/associations/collection_proxy.rb +159 -122
- data/lib/active_record/associations/foreign_association.rb +9 -0
- data/lib/active_record/associations/has_many_association.rb +23 -30
- 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 +43 -85
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
- data/lib/active_record/associations/join_dependency.rb +152 -177
- data/lib/active_record/associations/preloader/association.rb +101 -97
- data/lib/active_record/associations/preloader/through_association.rb +77 -76
- data/lib/active_record/associations/preloader.rb +94 -103
- data/lib/active_record/associations/singular_association.rb +12 -45
- data/lib/active_record/associations/through_association.rb +27 -15
- data/lib/active_record/associations.rb +1603 -1592
- data/lib/active_record/attribute_assignment.rb +54 -61
- data/lib/active_record/attribute_decorators.rb +38 -17
- data/lib/active_record/attribute_methods/before_type_cast.rb +12 -8
- data/lib/active_record/attribute_methods/dirty.rb +179 -109
- data/lib/active_record/attribute_methods/primary_key.rb +85 -92
- data/lib/active_record/attribute_methods/query.rb +4 -3
- data/lib/active_record/attribute_methods/read.rb +20 -49
- data/lib/active_record/attribute_methods/serialization.rb +29 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -66
- data/lib/active_record/attribute_methods/write.rb +34 -33
- data/lib/active_record/attribute_methods.rb +66 -106
- data/lib/active_record/attributes.rb +38 -25
- data/lib/active_record/autosave_association.rb +58 -39
- data/lib/active_record/base.rb +27 -24
- data/lib/active_record/callbacks.rb +64 -35
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +34 -13
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +558 -323
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +215 -94
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -35
- data/lib/active_record/connection_adapters/abstract/quoting.rb +128 -75
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -28
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +233 -147
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +400 -213
- data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -79
- data/lib/active_record/connection_adapters/abstract_adapter.rb +373 -202
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +401 -562
- data/lib/active_record/connection_adapters/column.rb +41 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +172 -139
- 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 +137 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -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 +268 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +48 -30
- data/lib/active_record/connection_adapters/postgresql/column.rb +19 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -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 -11
- 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 +12 -2
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
- 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 +44 -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 +30 -9
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -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 +8 -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 +20 -26
- 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 +34 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +378 -308
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +383 -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 +119 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
- 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 +261 -267
- data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
- data/lib/active_record/connection_handling.rb +143 -40
- data/lib/active_record/core.rb +207 -160
- data/lib/active_record/counter_cache.rb +60 -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 +78 -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 -87
- data/lib/active_record/enum.rb +67 -23
- data/lib/active_record/errors.rb +114 -18
- data/lib/active_record/explain.rb +4 -4
- 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 +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +194 -504
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +150 -99
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +116 -25
- data/lib/active_record/internal_metadata.rb +16 -19
- data/lib/active_record/legacy_yaml_adapter.rb +4 -2
- data/lib/active_record/locking/optimistic.rb +85 -86
- 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 +87 -0
- data/lib/active_record/middleware/database_selector.rb +74 -0
- data/lib/active_record/migration/command_recorder.rb +134 -100
- data/lib/active_record/migration/compatibility.rb +174 -56
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/migration.rb +369 -302
- data/lib/active_record/model_schema.rb +160 -127
- data/lib/active_record/nested_attributes.rb +213 -202
- data/lib/active_record/no_touching.rb +12 -3
- data/lib/active_record/null_relation.rb +12 -34
- data/lib/active_record/persistence.rb +446 -77
- data/lib/active_record/query_cache.rb +13 -12
- data/lib/active_record/querying.rb +37 -24
- 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 +312 -177
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +214 -254
- data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
- data/lib/active_record/relation/batches.rb +98 -52
- data/lib/active_record/relation/calculations.rb +212 -173
- data/lib/active_record/relation/delegation.rb +73 -69
- data/lib/active_record/relation/finder_methods.rb +207 -247
- data/lib/active_record/relation/from_clause.rb +6 -8
- data/lib/active_record/relation/merger.rb +82 -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 +83 -105
- data/lib/active_record/relation/query_attribute.rb +33 -2
- data/lib/active_record/relation/query_methods.rb +488 -332
- data/lib/active_record/relation/record_fetch_warning.rb +5 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -8
- data/lib/active_record/relation/where_clause.rb +111 -96
- data/lib/active_record/relation/where_clause_factory.rb +6 -11
- data/lib/active_record/relation.rb +443 -318
- data/lib/active_record/result.rb +69 -40
- 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 +16 -6
- data/lib/active_record/scoping/default.rb +92 -95
- data/lib/active_record/scoping/named.rb +51 -26
- data/lib/active_record/scoping.rb +20 -20
- 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 +6 -3
- data/lib/active_record/table_metadata.rb +39 -18
- data/lib/active_record/tasks/database_tasks.rb +271 -81
- data/lib/active_record/tasks/mysql_database_tasks.rb +54 -91
- data/lib/active_record/tasks/postgresql_database_tasks.rb +77 -47
- data/lib/active_record/tasks/sqlite_database_tasks.rb +33 -16
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +243 -0
- data/lib/active_record/timestamp.rb +70 -36
- data/lib/active_record/touch_later.rb +8 -6
- data/lib/active_record/transactions.rb +141 -157
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +44 -48
- 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 -4
- 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 -9
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +12 -1
- data/lib/active_record/type/type_map.rb +14 -17
- data/lib/active_record/type/unsigned_integer.rb +16 -0
- data/lib/active_record/type.rb +23 -18
- 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 -2
- 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 -5
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +37 -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 +256 -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 +203 -0
- data/lib/arel/visitors/dot.rb +296 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +156 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +158 -0
- data/lib/arel/visitors/oracle12.rb +65 -0
- data/lib/arel/visitors/postgresql.rb +109 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +888 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors/where_sql.rb +22 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +62 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -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 -3
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -30
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +138 -52
- 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 -132
- 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
- /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/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -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
|
@@ -25,7 +31,7 @@ module ActiveRecord
|
|
25
31
|
version_options = connection.internal_string_options_for_primary_key
|
26
32
|
|
27
33
|
connection.create_table(table_name, id: false) do |t|
|
28
|
-
t.string :version, version_options
|
34
|
+
t.string :version, **version_options
|
29
35
|
end
|
30
36
|
end
|
31
37
|
end
|
@@ -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,107 @@ module ActiveRecord
|
|
44
43
|
self.current_scope = nil
|
45
44
|
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
46
|
+
private
|
47
|
+
# Use this macro in your model to set a default scope for all operations on
|
48
|
+
# the model.
|
49
|
+
#
|
50
|
+
# class Article < ActiveRecord::Base
|
51
|
+
# default_scope { where(published: true) }
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# Article.all # => SELECT * FROM articles WHERE published = true
|
55
|
+
#
|
56
|
+
# The #default_scope is also applied while creating/building a record.
|
57
|
+
# It is not applied while updating a record.
|
58
|
+
#
|
59
|
+
# Article.new.published # => true
|
60
|
+
# Article.create.published # => true
|
61
|
+
#
|
62
|
+
# (You can also pass any object which responds to +call+ to the
|
63
|
+
# +default_scope+ macro, and it will be called when building the
|
64
|
+
# default scope.)
|
65
|
+
#
|
66
|
+
# If you use multiple #default_scope declarations in your model then
|
67
|
+
# they will be merged together:
|
68
|
+
#
|
69
|
+
# class Article < ActiveRecord::Base
|
70
|
+
# default_scope { where(published: true) }
|
71
|
+
# default_scope { where(rating: 'G') }
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'
|
75
|
+
#
|
76
|
+
# This is also the case with inheritance and module includes where the
|
77
|
+
# parent or module defines a #default_scope and the child or including
|
78
|
+
# class defines a second one.
|
79
|
+
#
|
80
|
+
# If you need to do more complex things with a default scope, you can
|
81
|
+
# alternatively define it as a class method:
|
82
|
+
#
|
83
|
+
# class Article < ActiveRecord::Base
|
84
|
+
# def self.default_scope
|
85
|
+
# # Should return a scope, you can call 'super' here etc.
|
86
|
+
# end
|
87
|
+
# end
|
88
|
+
def default_scope(scope = nil, &block) # :doc:
|
89
|
+
scope = block if block_given?
|
90
|
+
|
91
|
+
if scope.is_a?(Relation) || !scope.respond_to?(:call)
|
92
|
+
raise ArgumentError,
|
93
|
+
"Support for calling #default_scope without a block is removed. For example instead " \
|
94
|
+
"of `default_scope where(color: 'red')`, please use " \
|
95
|
+
"`default_scope { where(color: 'red') }`. (Alternatively you can just redefine " \
|
96
|
+
"self.default_scope.)"
|
97
|
+
end
|
92
98
|
|
93
|
-
|
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.)"
|
99
|
+
self.default_scopes += [scope]
|
99
100
|
end
|
100
101
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
def build_default_scope(base_rel = nil) # :nodoc:
|
105
|
-
return if abstract_class?
|
102
|
+
def build_default_scope(relation = relation())
|
103
|
+
return if abstract_class?
|
106
104
|
|
107
|
-
|
108
|
-
|
109
|
-
|
105
|
+
if default_scope_override.nil?
|
106
|
+
self.default_scope_override = !Base.is_a?(method(:default_scope).owner)
|
107
|
+
end
|
110
108
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
109
|
+
if default_scope_override
|
110
|
+
# The user has defined their own default scope method, so call that
|
111
|
+
evaluate_default_scope do
|
112
|
+
if scope = default_scope
|
113
|
+
relation.merge!(scope)
|
114
|
+
end
|
116
115
|
end
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
default_scope.merge(base_rel.instance_exec(&scope))
|
116
|
+
elsif default_scopes.any?
|
117
|
+
evaluate_default_scope do
|
118
|
+
default_scopes.inject(relation) do |default_scope, scope|
|
119
|
+
scope = scope.respond_to?(:to_proc) ? scope : scope.method(:call)
|
120
|
+
default_scope.instance_exec(&scope) || default_scope
|
121
|
+
end
|
124
122
|
end
|
125
123
|
end
|
126
124
|
end
|
127
|
-
end
|
128
|
-
|
129
|
-
def ignore_default_scope? # :nodoc:
|
130
|
-
ScopeRegistry.value_for(:ignore_default_scope, base_class)
|
131
|
-
end
|
132
125
|
|
133
|
-
|
134
|
-
|
135
|
-
|
126
|
+
def ignore_default_scope?
|
127
|
+
ScopeRegistry.value_for(:ignore_default_scope, base_class)
|
128
|
+
end
|
136
129
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
def evaluate_default_scope # :nodoc:
|
141
|
-
return if ignore_default_scope?
|
130
|
+
def ignore_default_scope=(ignore)
|
131
|
+
ScopeRegistry.set_value_for(:ignore_default_scope, base_class, ignore)
|
132
|
+
end
|
142
133
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
134
|
+
# The ignore_default_scope flag is used to prevent an infinite recursion
|
135
|
+
# situation where a default scope references a scope which has a default
|
136
|
+
# scope which references a scope...
|
137
|
+
def evaluate_default_scope
|
138
|
+
return if ignore_default_scope?
|
139
|
+
|
140
|
+
begin
|
141
|
+
self.ignore_default_scope = true
|
142
|
+
yield
|
143
|
+
ensure
|
144
|
+
self.ignore_default_scope = false
|
145
|
+
end
|
148
146
|
end
|
149
|
-
end
|
150
147
|
end
|
151
148
|
end
|
152
149
|
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,29 +24,42 @@ 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}.default_scoped`.
|
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)
|
39
53
|
end
|
40
54
|
end
|
41
55
|
|
42
|
-
|
56
|
+
# Returns a scope for the model with default scopes.
|
57
|
+
def default_scoped(scope = relation)
|
43
58
|
build_default_scope(scope) || scope
|
44
59
|
end
|
45
60
|
|
46
61
|
def default_extensions # :nodoc:
|
47
|
-
if scope =
|
62
|
+
if scope = scope_for_association || build_default_scope
|
48
63
|
scope.extensions
|
49
64
|
else
|
50
65
|
[]
|
@@ -54,7 +69,7 @@ module ActiveRecord
|
|
54
69
|
# Adds a class method for retrieving and querying objects.
|
55
70
|
# The method is intended to return an ActiveRecord::Relation
|
56
71
|
# object, which is composable with other scopes.
|
57
|
-
# If it returns nil or false
|
72
|
+
# If it returns +nil+ or +false+, an
|
58
73
|
# {all}[rdoc-ref:Scoping::Named::ClassMethods#all] scope is returned instead.
|
59
74
|
#
|
60
75
|
# A \scope represents a narrowing of a database query, such as
|
@@ -154,7 +169,7 @@ module ActiveRecord
|
|
154
169
|
# Article.featured.titles
|
155
170
|
def scope(name, body, &block)
|
156
171
|
unless body.respond_to?(:call)
|
157
|
-
raise ArgumentError,
|
172
|
+
raise ArgumentError, "The scope body needs to be callable."
|
158
173
|
end
|
159
174
|
|
160
175
|
if dangerous_class_method?(name)
|
@@ -163,34 +178,44 @@ module ActiveRecord
|
|
163
178
|
"a class method with the same name."
|
164
179
|
end
|
165
180
|
|
181
|
+
if method_defined_within?(name, Relation)
|
182
|
+
raise ArgumentError, "You tried to define a scope named \"#{name}\" " \
|
183
|
+
"on the model \"#{self.name}\", but ActiveRecord::Relation already defined " \
|
184
|
+
"an instance method with the same name."
|
185
|
+
end
|
186
|
+
|
166
187
|
valid_scope_name?(name)
|
167
188
|
extension = Module.new(&block) if block
|
168
189
|
|
169
190
|
if body.respond_to?(:to_proc)
|
170
|
-
singleton_class.
|
171
|
-
scope = all.
|
191
|
+
singleton_class.define_method(name) do |*args|
|
192
|
+
scope = all._exec_scope(name, *args, &body)
|
172
193
|
scope = scope.extending(extension) if extension
|
173
|
-
|
174
|
-
scope || all
|
194
|
+
scope
|
175
195
|
end
|
176
196
|
else
|
177
|
-
singleton_class.
|
178
|
-
scope =
|
197
|
+
singleton_class.define_method(name) do |*args|
|
198
|
+
scope = body.call(*args) || all
|
179
199
|
scope = scope.extending(extension) if extension
|
180
|
-
|
181
|
-
scope || all
|
200
|
+
scope
|
182
201
|
end
|
183
202
|
end
|
203
|
+
singleton_class.send(:ruby2_keywords, name) if respond_to?(:ruby2_keywords, true)
|
204
|
+
|
205
|
+
generate_relation_method(name)
|
184
206
|
end
|
185
207
|
|
186
|
-
|
208
|
+
private
|
209
|
+
def singleton_method_added(name)
|
210
|
+
generate_relation_method(name) if Kernel.respond_to?(name) && !ActiveRecord::Relation.method_defined?(name)
|
211
|
+
end
|
187
212
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
213
|
+
def valid_scope_name?(name)
|
214
|
+
if respond_to?(name, true) && logger
|
215
|
+
logger.warn "Creating scope :#{name}. " \
|
216
|
+
"Overwriting existing method #{self.name}.#{name}."
|
217
|
+
end
|
192
218
|
end
|
193
|
-
end
|
194
219
|
end
|
195
220
|
end
|
196
221
|
end
|