activerecord 3.2.6 → 6.0.0
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 +611 -6417
- data/MIT-LICENSE +4 -2
- data/README.rdoc +44 -47
- data/examples/performance.rb +79 -71
- data/examples/simple.rb +6 -5
- data/lib/active_record/aggregations.rb +268 -238
- data/lib/active_record/association_relation.rb +40 -0
- data/lib/active_record/associations/alias_tracker.rb +47 -42
- data/lib/active_record/associations/association.rb +173 -81
- data/lib/active_record/associations/association_scope.rb +124 -92
- data/lib/active_record/associations/belongs_to_association.rb +83 -38
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +11 -9
- data/lib/active_record/associations/builder/association.rb +113 -32
- data/lib/active_record/associations/builder/belongs_to.rb +105 -60
- data/lib/active_record/associations/builder/collection_association.rb +53 -56
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +98 -41
- data/lib/active_record/associations/builder/has_many.rb +11 -63
- data/lib/active_record/associations/builder/has_one.rb +47 -45
- data/lib/active_record/associations/builder/singular_association.rb +30 -18
- data/lib/active_record/associations/collection_association.rb +217 -295
- data/lib/active_record/associations/collection_proxy.rb +1074 -77
- data/lib/active_record/associations/foreign_association.rb +20 -0
- data/lib/active_record/associations/has_many_association.rb +78 -50
- data/lib/active_record/associations/has_many_through_association.rb +99 -61
- data/lib/active_record/associations/has_one_association.rb +75 -30
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +45 -119
- data/lib/active_record/associations/join_dependency/join_base.rb +11 -12
- data/lib/active_record/associations/join_dependency/join_part.rb +35 -42
- data/lib/active_record/associations/join_dependency.rb +208 -164
- data/lib/active_record/associations/preloader/association.rb +93 -87
- data/lib/active_record/associations/preloader/through_association.rb +87 -38
- data/lib/active_record/associations/preloader.rb +134 -110
- data/lib/active_record/associations/singular_association.rb +19 -24
- data/lib/active_record/associations/through_association.rb +61 -27
- data/lib/active_record/associations.rb +1766 -1505
- data/lib/active_record/attribute_assignment.rb +57 -193
- data/lib/active_record/attribute_decorators.rb +90 -0
- data/lib/active_record/attribute_methods/before_type_cast.rb +58 -8
- data/lib/active_record/attribute_methods/dirty.rb +187 -67
- data/lib/active_record/attribute_methods/primary_key.rb +100 -78
- data/lib/active_record/attribute_methods/query.rb +10 -8
- data/lib/active_record/attribute_methods/read.rb +29 -118
- data/lib/active_record/attribute_methods/serialization.rb +60 -72
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +69 -42
- data/lib/active_record/attribute_methods/write.rb +36 -44
- data/lib/active_record/attribute_methods.rb +306 -161
- data/lib/active_record/attributes.rb +279 -0
- data/lib/active_record/autosave_association.rb +324 -238
- data/lib/active_record/base.rb +114 -507
- data/lib/active_record/callbacks.rb +147 -83
- data/lib/active_record/coders/json.rb +15 -0
- data/lib/active_record/coders/yaml_column.rb +32 -23
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +962 -279
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +32 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +331 -209
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +95 -23
- data/lib/active_record/connection_adapters/abstract/quoting.rb +201 -65
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +23 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +510 -289
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +93 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1182 -313
- data/lib/active_record/connection_adapters/abstract/transaction.rb +323 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +585 -120
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +610 -463
- data/lib/active_record/connection_adapters/column.rb +58 -233
- data/lib/active_record/connection_adapters/connection_specification.rb +297 -0
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +75 -207
- data/lib/active_record/connection_adapters/postgresql/column.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +182 -0
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +92 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +53 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +17 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +21 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +71 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +41 -0
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +65 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +97 -0
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +18 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +113 -0
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +26 -0
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +34 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +205 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +222 -0
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +776 -0
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +81 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +695 -1052
- data/lib/active_record/connection_adapters/schema_cache.rb +115 -24
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
- 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 +528 -26
- data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
- data/lib/active_record/connection_handling.rb +267 -0
- data/lib/active_record/core.rb +599 -0
- data/lib/active_record/counter_cache.rb +177 -103
- 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 +107 -64
- data/lib/active_record/enum.rb +274 -0
- data/lib/active_record/errors.rb +254 -61
- data/lib/active_record/explain.rb +35 -70
- data/lib/active_record/explain_registry.rb +32 -0
- data/lib/active_record/explain_subscriber.rb +18 -8
- data/lib/active_record/fixture_set/file.rb +82 -0
- 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 +291 -475
- data/lib/active_record/gem_version.rb +17 -0
- data/lib/active_record/inheritance.rb +219 -100
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +175 -17
- data/lib/active_record/internal_metadata.rb +53 -0
- data/lib/active_record/legacy_yaml_adapter.rb +48 -0
- data/lib/active_record/locale/en.yml +9 -1
- data/lib/active_record/locking/optimistic.rb +106 -92
- data/lib/active_record/locking/pessimistic.rb +23 -11
- data/lib/active_record/log_subscriber.rb +80 -30
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/migration/command_recorder.rb +235 -56
- data/lib/active_record/migration/compatibility.rb +244 -0
- data/lib/active_record/migration/join_table.rb +17 -0
- data/lib/active_record/migration.rb +917 -301
- data/lib/active_record/model_schema.rb +351 -175
- data/lib/active_record/nested_attributes.rb +366 -235
- data/lib/active_record/no_touching.rb +65 -0
- data/lib/active_record/null_relation.rb +68 -0
- data/lib/active_record/persistence.rb +761 -166
- data/lib/active_record/query_cache.rb +22 -44
- data/lib/active_record/querying.rb +55 -31
- data/lib/active_record/railtie.rb +185 -47
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/console_sandbox.rb +5 -4
- data/lib/active_record/railties/controller_runtime.rb +35 -33
- data/lib/active_record/railties/databases.rake +366 -463
- data/lib/active_record/readonly_attributes.rb +4 -6
- data/lib/active_record/reflection.rb +736 -228
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/batches.rb +252 -52
- data/lib/active_record/relation/calculations.rb +340 -270
- data/lib/active_record/relation/delegation.rb +117 -36
- data/lib/active_record/relation/finder_methods.rb +439 -286
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +184 -0
- data/lib/active_record/relation/predicate_builder/array_handler.rb +49 -0
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder.rb +131 -39
- data/lib/active_record/relation/query_attribute.rb +50 -0
- data/lib/active_record/relation/query_methods.rb +1163 -221
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +49 -120
- data/lib/active_record/relation/where_clause.rb +190 -0
- data/lib/active_record/relation/where_clause_factory.rb +33 -0
- data/lib/active_record/relation.rb +671 -349
- data/lib/active_record/result.rb +149 -15
- data/lib/active_record/runtime_registry.rb +24 -0
- data/lib/active_record/sanitization.rb +153 -133
- data/lib/active_record/schema.rb +22 -19
- data/lib/active_record/schema_dumper.rb +178 -112
- data/lib/active_record/schema_migration.rb +60 -0
- data/lib/active_record/scoping/default.rb +107 -98
- data/lib/active_record/scoping/named.rb +130 -115
- data/lib/active_record/scoping.rb +77 -123
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +10 -6
- data/lib/active_record/statement_cache.rb +148 -0
- data/lib/active_record/store.rb +256 -16
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +75 -0
- data/lib/active_record/tasks/database_tasks.rb +506 -0
- data/lib/active_record/tasks/mysql_database_tasks.rb +115 -0
- data/lib/active_record/tasks/postgresql_database_tasks.rb +141 -0
- data/lib/active_record/tasks/sqlite_database_tasks.rb +77 -0
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +224 -0
- data/lib/active_record/timestamp.rb +93 -39
- data/lib/active_record/touch_later.rb +66 -0
- data/lib/active_record/transactions.rb +260 -129
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +129 -0
- data/lib/active_record/type/date.rb +9 -0
- data/lib/active_record/type/date_time.rb +9 -0
- data/lib/active_record/type/decimal_without_scale.rb +15 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +25 -0
- data/lib/active_record/type/internal/timezone.rb +17 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +71 -0
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +21 -0
- data/lib/active_record/type/type_map.rb +62 -0
- data/lib/active_record/type/unsigned_integer.rb +17 -0
- data/lib/active_record/type.rb +78 -0
- data/lib/active_record/type_caster/connection.rb +34 -0
- data/lib/active_record/type_caster/map.rb +20 -0
- data/lib/active_record/type_caster.rb +9 -0
- data/lib/active_record/validations/absence.rb +25 -0
- data/lib/active_record/validations/associated.rb +35 -18
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +68 -0
- data/lib/active_record/validations/uniqueness.rb +123 -77
- data/lib/active_record/validations.rb +54 -43
- data/lib/active_record/version.rb +7 -7
- data/lib/active_record.rb +97 -49
- 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 +51 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +59 -9
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +48 -0
- data/lib/rails/generators/active_record/migration.rb +41 -8
- data/lib/rails/generators/active_record/model/model_generator.rb +24 -22
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +1 -1
- data/lib/rails/generators/active_record.rb +10 -16
- metadata +285 -149
- data/examples/associations.png +0 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
- data/lib/active_record/associations/join_helper.rb +0 -55
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -24
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -15
- data/lib/active_record/associations/preloader/has_one.rb +0 -23
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -21
- data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -188
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -426
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -579
- data/lib/active_record/dynamic_finder_match.rb +0 -68
- data/lib/active_record/dynamic_scope_match.rb +0 -23
- data/lib/active_record/fixtures/file.rb +0 -65
- data/lib/active_record/identity_map.rb +0 -162
- data/lib/active_record/observer.rb +0 -121
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -203
- data/lib/active_record/session_store.rb +0 -358
- data/lib/active_record/test_case.rb +0 -73
- data/lib/rails/generators/active_record/migration/templates/migration.rb +0 -34
- data/lib/rails/generators/active_record/model/templates/migration.rb +0 -15
- data/lib/rails/generators/active_record/model/templates/model.rb +0 -12
- data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
- data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
- data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
- data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Scoping
|
@@ -6,136 +6,145 @@ module ActiveRecord
|
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
8
|
included do
|
9
|
-
# Stores the default scope for the class
|
10
|
-
class_attribute :default_scopes, :
|
11
|
-
|
9
|
+
# Stores the default scope for the class.
|
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
|
12
12
|
end
|
13
13
|
|
14
14
|
module ClassMethods
|
15
|
-
# Returns a scope for the model without the
|
15
|
+
# Returns a scope for the model without the previously set scopes.
|
16
16
|
#
|
17
17
|
# class Post < ActiveRecord::Base
|
18
18
|
# def self.default_scope
|
19
|
-
# where
|
19
|
+
# where(published: true)
|
20
20
|
# end
|
21
21
|
# end
|
22
22
|
#
|
23
|
-
# Post.all
|
24
|
-
# Post.unscoped.all
|
23
|
+
# Post.all # Fires "SELECT * FROM posts WHERE published = true"
|
24
|
+
# Post.unscoped.all # Fires "SELECT * FROM posts"
|
25
|
+
# Post.where(published: false).unscoped.all # Fires "SELECT * FROM posts"
|
25
26
|
#
|
26
27
|
# This method also accepts a block. All queries inside the block will
|
27
|
-
# not use the
|
28
|
+
# not use the previously set scopes.
|
28
29
|
#
|
29
30
|
# Post.unscoped {
|
30
31
|
# Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10"
|
31
32
|
# }
|
32
|
-
|
33
|
-
# It is recommended to use the block form of unscoped because chaining
|
34
|
-
# unscoped with <tt>scope</tt> does not work. Assuming that
|
35
|
-
# <tt>published</tt> is a <tt>scope</tt>, the following two statements
|
36
|
-
# are equal: the default_scope is applied on both.
|
37
|
-
#
|
38
|
-
# Post.unscoped.published
|
39
|
-
# Post.published
|
40
|
-
def unscoped #:nodoc:
|
33
|
+
def unscoped
|
41
34
|
block_given? ? relation.scoping { yield } : relation
|
42
35
|
end
|
43
36
|
|
37
|
+
# Are there attributes associated with this scope?
|
38
|
+
def scope_attributes? # :nodoc:
|
39
|
+
super || default_scopes.any? || respond_to?(:default_scope)
|
40
|
+
end
|
41
|
+
|
44
42
|
def before_remove_const #:nodoc:
|
45
43
|
self.current_scope = nil
|
46
44
|
end
|
47
45
|
|
48
|
-
|
46
|
+
private
|
49
47
|
|
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
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
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
|
99
|
+
|
100
|
+
self.default_scopes += [scope]
|
101
|
+
end
|
102
|
+
|
103
|
+
def build_default_scope(relation = relation())
|
104
|
+
return if abstract_class?
|
105
|
+
|
106
|
+
if default_scope_override.nil?
|
107
|
+
self.default_scope_override = !Base.is_a?(method(:default_scope).owner)
|
108
|
+
end
|
99
109
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
default_scope.
|
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
|
+
end
|
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
|
112
122
|
end
|
113
123
|
end
|
114
124
|
end
|
115
125
|
end
|
116
|
-
end
|
117
126
|
|
118
|
-
|
119
|
-
|
120
|
-
|
127
|
+
def ignore_default_scope?
|
128
|
+
ScopeRegistry.value_for(:ignore_default_scope, base_class)
|
129
|
+
end
|
121
130
|
|
122
|
-
|
123
|
-
|
124
|
-
|
131
|
+
def ignore_default_scope=(ignore)
|
132
|
+
ScopeRegistry.set_value_for(:ignore_default_scope, base_class, ignore)
|
133
|
+
end
|
125
134
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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?
|
130
140
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
141
|
+
begin
|
142
|
+
self.ignore_default_scope = true
|
143
|
+
yield
|
144
|
+
ensure
|
145
|
+
self.ignore_default_scope = false
|
146
|
+
end
|
136
147
|
end
|
137
|
-
end
|
138
|
-
|
139
148
|
end
|
140
149
|
end
|
141
150
|
end
|
@@ -1,139 +1,136 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
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"
|
6
6
|
|
7
7
|
module ActiveRecord
|
8
|
-
# = Active Record Named \Scopes
|
8
|
+
# = Active Record \Named \Scopes
|
9
9
|
module Scoping
|
10
10
|
module Named
|
11
11
|
extend ActiveSupport::Concern
|
12
12
|
|
13
13
|
module ClassMethods
|
14
|
-
# Returns an
|
14
|
+
# Returns an ActiveRecord::Relation scope object.
|
15
15
|
#
|
16
|
-
# posts = Post.
|
16
|
+
# posts = Post.all
|
17
17
|
# posts.size # Fires "select count(*) from posts" and returns the count
|
18
18
|
# posts.each {|p| puts p.name } # Fires "select * from posts" and loads post objects
|
19
19
|
#
|
20
|
-
# fruits = Fruit.
|
21
|
-
# fruits = fruits.where(:
|
20
|
+
# fruits = Fruit.all
|
21
|
+
# fruits = fruits.where(color: 'red') if options[:red_only]
|
22
22
|
# fruits = fruits.limit(10) if limited?
|
23
23
|
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
24
|
+
# You can define a scope that applies to all finders using
|
25
|
+
# {default_scope}[rdoc-ref:Scoping::Default::ClassMethods#default_scope].
|
26
|
+
def all
|
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
|
36
40
|
else
|
37
|
-
|
38
|
-
scope.default_scoped = true
|
39
|
-
scope
|
41
|
+
relation.merge!(scope)
|
40
42
|
end
|
43
|
+
else
|
44
|
+
default_scoped
|
41
45
|
end
|
42
46
|
end
|
43
47
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
def scope_attributes # :nodoc:
|
48
|
-
if current_scope
|
49
|
-
current_scope.scope_for_create
|
48
|
+
def scope_for_association(scope = relation) # :nodoc:
|
49
|
+
if current_scope&.empty_scope?
|
50
|
+
scope
|
50
51
|
else
|
51
|
-
scope
|
52
|
-
scope.default_scoped = true
|
53
|
-
scope.scope_for_create
|
52
|
+
default_scoped(scope)
|
54
53
|
end
|
55
54
|
end
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
def scope_attributes? # :nodoc:
|
60
|
-
current_scope || default_scopes.any?
|
56
|
+
def default_scoped(scope = relation) # :nodoc:
|
57
|
+
build_default_scope(scope) || scope
|
61
58
|
end
|
62
59
|
|
63
|
-
|
64
|
-
|
60
|
+
def default_extensions # :nodoc:
|
61
|
+
if scope = scope_for_association || build_default_scope
|
62
|
+
scope.extensions
|
63
|
+
else
|
64
|
+
[]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Adds a class method for retrieving and querying objects.
|
69
|
+
# The method is intended to return an ActiveRecord::Relation
|
70
|
+
# object, which is composable with other scopes.
|
71
|
+
# If it returns +nil+ or +false+, an
|
72
|
+
# {all}[rdoc-ref:Scoping::Named::ClassMethods#all] scope is returned instead.
|
73
|
+
#
|
74
|
+
# A \scope represents a narrowing of a database query, such as
|
75
|
+
# <tt>where(color: :red).select('shirts.*').includes(:washing_instructions)</tt>.
|
65
76
|
#
|
66
77
|
# class Shirt < ActiveRecord::Base
|
67
|
-
# scope :red, where(:
|
68
|
-
# scope :dry_clean_only, joins(:washing_instructions).where('washing_instructions.dry_clean_only = ?', true)
|
78
|
+
# scope :red, -> { where(color: 'red') }
|
79
|
+
# scope :dry_clean_only, -> { joins(:washing_instructions).where('washing_instructions.dry_clean_only = ?', true) }
|
69
80
|
# end
|
70
81
|
#
|
71
|
-
# The above calls to
|
72
|
-
#
|
82
|
+
# The above calls to #scope define class methods <tt>Shirt.red</tt> and
|
83
|
+
# <tt>Shirt.dry_clean_only</tt>. <tt>Shirt.red</tt>, in effect,
|
84
|
+
# represents the query <tt>Shirt.where(color: 'red')</tt>.
|
85
|
+
#
|
86
|
+
# You should always pass a callable object to the scopes defined
|
87
|
+
# with #scope. This ensures that the scope is re-evaluated each
|
88
|
+
# time it is called.
|
73
89
|
#
|
74
|
-
# Note that this is simply 'syntactic sugar' for defining an actual
|
90
|
+
# Note that this is simply 'syntactic sugar' for defining an actual
|
91
|
+
# class method:
|
75
92
|
#
|
76
93
|
# class Shirt < ActiveRecord::Base
|
77
94
|
# def self.red
|
78
|
-
# where(:
|
95
|
+
# where(color: 'red')
|
79
96
|
# end
|
80
97
|
# end
|
81
98
|
#
|
82
|
-
# Unlike <tt>Shirt.find(...)</tt>, however, the object returned by
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
#
|
99
|
+
# Unlike <tt>Shirt.find(...)</tt>, however, the object returned by
|
100
|
+
# <tt>Shirt.red</tt> is not an Array but an ActiveRecord::Relation,
|
101
|
+
# which is composable with other scopes; it resembles the association object
|
102
|
+
# constructed by a {has_many}[rdoc-ref:Associations::ClassMethods#has_many]
|
103
|
+
# declaration. For instance, you can invoke <tt>Shirt.red.first</tt>, <tt>Shirt.red.count</tt>,
|
104
|
+
# <tt>Shirt.red.where(size: 'small')</tt>. Also, just as with the
|
105
|
+
# association objects, named \scopes act like an Array, implementing
|
106
|
+
# Enumerable; <tt>Shirt.red.each(&block)</tt>, <tt>Shirt.red.first</tt>,
|
107
|
+
# and <tt>Shirt.red.inject(memo, &block)</tt> all behave as if
|
108
|
+
# <tt>Shirt.red</tt> really was an array.
|
109
|
+
#
|
110
|
+
# These named \scopes are composable. For instance,
|
111
|
+
# <tt>Shirt.red.dry_clean_only</tt> will produce all shirts that are
|
112
|
+
# both red and dry clean only. Nested finds and calculations also work
|
113
|
+
# with these compositions: <tt>Shirt.red.dry_clean_only.count</tt>
|
114
|
+
# returns the number of garments for which these criteria obtain.
|
115
|
+
# Similarly with <tt>Shirt.red.dry_clean_only.average(:thread_count)</tt>.
|
116
|
+
#
|
117
|
+
# All scopes are available as class methods on the ActiveRecord::Base
|
118
|
+
# descendant upon which the \scopes were defined. But they are also
|
119
|
+
# available to {has_many}[rdoc-ref:Associations::ClassMethods#has_many]
|
120
|
+
# associations. If,
|
97
121
|
#
|
98
122
|
# class Person < ActiveRecord::Base
|
99
123
|
# has_many :shirts
|
100
124
|
# end
|
101
125
|
#
|
102
|
-
# then <tt>elton.shirts.red.dry_clean_only</tt> will return all of
|
103
|
-
# only shirts.
|
104
|
-
#
|
105
|
-
# Named \scopes can also be procedural:
|
106
|
-
#
|
107
|
-
# class Shirt < ActiveRecord::Base
|
108
|
-
# scope :colored, lambda { |color| where(:color => color) }
|
109
|
-
# end
|
110
|
-
#
|
111
|
-
# In this example, <tt>Shirt.colored('puce')</tt> finds all puce shirts.
|
126
|
+
# then <tt>elton.shirts.red.dry_clean_only</tt> will return all of
|
127
|
+
# Elton's red, dry clean only shirts.
|
112
128
|
#
|
113
|
-
#
|
114
|
-
#
|
115
|
-
# scope :colored, ->(color) { where(:color => color) }
|
116
|
-
#
|
117
|
-
# Note that scopes defined with \scope will be evaluated when they are defined, rather than
|
118
|
-
# when they are used. For example, the following would be incorrect:
|
119
|
-
#
|
120
|
-
# class Post < ActiveRecord::Base
|
121
|
-
# scope :recent, where('published_at >= ?', Time.current - 1.week)
|
122
|
-
# end
|
123
|
-
#
|
124
|
-
# The example above would be 'frozen' to the <tt>Time.current</tt> value when the <tt>Post</tt>
|
125
|
-
# class was defined, and so the resultant SQL query would always be the same. The correct
|
126
|
-
# way to do this would be via a lambda, which will re-evaluate the scope each time
|
127
|
-
# it is called:
|
128
|
-
#
|
129
|
-
# class Post < ActiveRecord::Base
|
130
|
-
# scope :recent, lambda { where('published_at >= ?', Time.current - 1.week) }
|
131
|
-
# end
|
132
|
-
#
|
133
|
-
# Named \scopes can also have extensions, just as with <tt>has_many</tt> declarations:
|
129
|
+
# \Named scopes can also have extensions, just as with
|
130
|
+
# {has_many}[rdoc-ref:Associations::ClassMethods#has_many] declarations:
|
134
131
|
#
|
135
132
|
# class Shirt < ActiveRecord::Base
|
136
|
-
# scope :red, where(:
|
133
|
+
# scope :red, -> { where(color: 'red') } do
|
137
134
|
# def dom_id
|
138
135
|
# 'red_shirts'
|
139
136
|
# end
|
@@ -143,59 +140,77 @@ module ActiveRecord
|
|
143
140
|
# Scopes can also be used while creating/building a record.
|
144
141
|
#
|
145
142
|
# class Article < ActiveRecord::Base
|
146
|
-
# scope :published, where(:
|
143
|
+
# scope :published, -> { where(published: true) }
|
147
144
|
# end
|
148
145
|
#
|
149
146
|
# Article.published.new.published # => true
|
150
147
|
# Article.published.create.published # => true
|
151
148
|
#
|
152
|
-
# Class methods on your model are automatically available
|
149
|
+
# \Class methods on your model are automatically available
|
153
150
|
# on scopes. Assuming the following setup:
|
154
151
|
#
|
155
152
|
# class Article < ActiveRecord::Base
|
156
|
-
# scope :published, where(:
|
157
|
-
# scope :featured, where(:
|
153
|
+
# scope :published, -> { where(published: true) }
|
154
|
+
# scope :featured, -> { where(featured: true) }
|
158
155
|
#
|
159
156
|
# def self.latest_article
|
160
157
|
# order('published_at desc').first
|
161
158
|
# end
|
162
159
|
#
|
163
160
|
# def self.titles
|
164
|
-
#
|
161
|
+
# pluck(:title)
|
165
162
|
# end
|
166
|
-
#
|
167
163
|
# end
|
168
164
|
#
|
169
165
|
# We are able to call the methods like this:
|
170
166
|
#
|
171
167
|
# Article.published.featured.latest_article
|
172
168
|
# Article.featured.titles
|
169
|
+
def scope(name, body, &block)
|
170
|
+
unless body.respond_to?(:call)
|
171
|
+
raise ArgumentError, "The scope body needs to be callable."
|
172
|
+
end
|
173
173
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
174
|
+
if dangerous_class_method?(name)
|
175
|
+
raise ArgumentError, "You tried to define a scope named \"#{name}\" " \
|
176
|
+
"on the model \"#{self.name}\", but Active Record already defined " \
|
177
|
+
"a class method with the same name."
|
178
|
+
end
|
178
179
|
|
179
|
-
|
180
|
-
|
181
|
-
|
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
|
182
185
|
|
183
|
-
|
186
|
+
valid_scope_name?(name)
|
187
|
+
extension = Module.new(&block) if block
|
184
188
|
|
185
|
-
|
189
|
+
if body.respond_to?(:to_proc)
|
190
|
+
singleton_class.define_method(name) do |*args|
|
191
|
+
scope = all._exec_scope(name, *args, &body)
|
192
|
+
scope = scope.extending(extension) if extension
|
193
|
+
scope
|
194
|
+
end
|
195
|
+
else
|
196
|
+
singleton_class.define_method(name) do |*args|
|
197
|
+
scope = body.call(*args) || all
|
198
|
+
scope = scope.extending(extension) if extension
|
199
|
+
scope
|
200
|
+
end
|
186
201
|
end
|
187
202
|
|
188
|
-
|
203
|
+
generate_relation_method(name)
|
189
204
|
end
|
190
205
|
|
191
|
-
|
206
|
+
private
|
192
207
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
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
|
197
213
|
end
|
198
|
-
end
|
199
214
|
end
|
200
215
|
end
|
201
216
|
end
|