activerecord 4.1.8 → 4.2.11.3
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 +1165 -1591
- data/README.rdoc +15 -10
- data/lib/active_record/aggregations.rb +15 -8
- data/lib/active_record/association_relation.rb +13 -0
- data/lib/active_record/associations/alias_tracker.rb +3 -12
- data/lib/active_record/associations/association.rb +16 -4
- data/lib/active_record/associations/association_scope.rb +84 -43
- data/lib/active_record/associations/belongs_to_association.rb +28 -10
- data/lib/active_record/associations/builder/association.rb +16 -5
- data/lib/active_record/associations/builder/belongs_to.rb +7 -29
- data/lib/active_record/associations/builder/collection_association.rb +5 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +9 -14
- data/lib/active_record/associations/builder/has_many.rb +1 -1
- data/lib/active_record/associations/builder/has_one.rb +2 -2
- data/lib/active_record/associations/builder/singular_association.rb +8 -1
- data/lib/active_record/associations/collection_association.rb +87 -30
- data/lib/active_record/associations/collection_proxy.rb +33 -35
- data/lib/active_record/associations/foreign_association.rb +11 -0
- data/lib/active_record/associations/has_many_association.rb +83 -22
- data/lib/active_record/associations/has_many_through_association.rb +49 -26
- data/lib/active_record/associations/has_one_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +25 -15
- data/lib/active_record/associations/join_dependency/join_part.rb +0 -1
- data/lib/active_record/associations/join_dependency.rb +26 -12
- data/lib/active_record/associations/preloader/association.rb +14 -10
- data/lib/active_record/associations/preloader/through_association.rb +4 -3
- data/lib/active_record/associations/preloader.rb +37 -26
- data/lib/active_record/associations/singular_association.rb +17 -2
- data/lib/active_record/associations/through_association.rb +16 -12
- data/lib/active_record/associations.rb +158 -49
- data/lib/active_record/attribute.rb +163 -0
- data/lib/active_record/attribute_assignment.rb +20 -12
- data/lib/active_record/attribute_decorators.rb +66 -0
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
- data/lib/active_record/attribute_methods/dirty.rb +107 -43
- data/lib/active_record/attribute_methods/primary_key.rb +7 -8
- data/lib/active_record/attribute_methods/query.rb +1 -1
- data/lib/active_record/attribute_methods/read.rb +22 -59
- data/lib/active_record/attribute_methods/serialization.rb +16 -150
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +38 -28
- data/lib/active_record/attribute_methods/write.rb +9 -24
- data/lib/active_record/attribute_methods.rb +57 -95
- data/lib/active_record/attribute_set/builder.rb +106 -0
- data/lib/active_record/attribute_set.rb +81 -0
- data/lib/active_record/attributes.rb +147 -0
- data/lib/active_record/autosave_association.rb +30 -12
- data/lib/active_record/base.rb +13 -24
- data/lib/active_record/callbacks.rb +6 -6
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +85 -53
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +52 -50
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/quoting.rb +60 -60
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +39 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +139 -57
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -34
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +271 -74
- data/lib/active_record/connection_adapters/abstract/transaction.rb +125 -118
- data/lib/active_record/connection_adapters/abstract_adapter.rb +177 -60
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +295 -141
- data/lib/active_record/connection_adapters/column.rb +29 -240
- data/lib/active_record/connection_adapters/connection_specification.rb +15 -24
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +17 -33
- data/lib/active_record/connection_adapters/mysql_adapter.rb +68 -145
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +15 -27
- data/lib/active_record/connection_adapters/postgresql/column.rb +20 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +40 -25
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +100 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +52 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +46 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +11 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +19 -0
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +21 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +59 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +11 -0
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +35 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +79 -0
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +19 -0
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +11 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +109 -0
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +21 -0
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +26 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +29 -385
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +46 -136
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +152 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +134 -43
- data/lib/active_record/connection_adapters/postgresql/utils.rb +77 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +224 -477
- data/lib/active_record/connection_adapters/schema_cache.rb +14 -28
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -75
- data/lib/active_record/connection_handling.rb +1 -1
- data/lib/active_record/core.rb +163 -40
- data/lib/active_record/counter_cache.rb +60 -6
- data/lib/active_record/enum.rb +10 -12
- data/lib/active_record/errors.rb +53 -30
- data/lib/active_record/explain.rb +1 -1
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixtures.rb +62 -74
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +35 -10
- data/lib/active_record/integration.rb +4 -4
- data/lib/active_record/legacy_yaml_adapter.rb +30 -0
- data/lib/active_record/locking/optimistic.rb +46 -26
- data/lib/active_record/migration/command_recorder.rb +19 -2
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +79 -47
- data/lib/active_record/model_schema.rb +52 -58
- data/lib/active_record/nested_attributes.rb +18 -8
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/persistence.rb +48 -27
- data/lib/active_record/query_cache.rb +3 -3
- data/lib/active_record/querying.rb +10 -7
- data/lib/active_record/railtie.rb +19 -14
- data/lib/active_record/railties/databases.rake +55 -56
- data/lib/active_record/readonly_attributes.rb +0 -1
- data/lib/active_record/reflection.rb +281 -117
- data/lib/active_record/relation/batches.rb +0 -1
- data/lib/active_record/relation/calculations.rb +41 -37
- data/lib/active_record/relation/delegation.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +71 -48
- data/lib/active_record/relation/merger.rb +39 -29
- data/lib/active_record/relation/predicate_builder/array_handler.rb +32 -13
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +42 -12
- data/lib/active_record/relation/query_methods.rb +130 -73
- data/lib/active_record/relation/spawn_methods.rb +10 -3
- data/lib/active_record/relation.rb +57 -25
- data/lib/active_record/result.rb +18 -7
- data/lib/active_record/sanitization.rb +12 -2
- data/lib/active_record/schema.rb +0 -1
- data/lib/active_record/schema_dumper.rb +59 -28
- data/lib/active_record/schema_migration.rb +5 -4
- data/lib/active_record/scoping/default.rb +6 -4
- data/lib/active_record/scoping/named.rb +4 -0
- data/lib/active_record/serializers/xml_serializer.rb +3 -7
- data/lib/active_record/statement_cache.rb +95 -10
- data/lib/active_record/store.rb +5 -5
- data/lib/active_record/tasks/database_tasks.rb +61 -8
- data/lib/active_record/tasks/mysql_database_tasks.rb +32 -17
- data/lib/active_record/tasks/postgresql_database_tasks.rb +20 -9
- data/lib/active_record/timestamp.rb +9 -7
- data/lib/active_record/transactions.rb +54 -28
- data/lib/active_record/type/big_integer.rb +13 -0
- data/lib/active_record/type/binary.rb +50 -0
- data/lib/active_record/type/boolean.rb +31 -0
- data/lib/active_record/type/date.rb +50 -0
- data/lib/active_record/type/date_time.rb +54 -0
- data/lib/active_record/type/decimal.rb +64 -0
- data/lib/active_record/type/decimal_without_scale.rb +11 -0
- data/lib/active_record/type/decorator.rb +14 -0
- data/lib/active_record/type/float.rb +19 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +23 -0
- data/lib/active_record/type/integer.rb +59 -0
- data/lib/active_record/type/mutable.rb +16 -0
- data/lib/active_record/type/numeric.rb +36 -0
- data/lib/active_record/type/serialized.rb +62 -0
- data/lib/active_record/type/string.rb +40 -0
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +26 -0
- data/lib/active_record/type/time_value.rb +38 -0
- data/lib/active_record/type/type_map.rb +64 -0
- data/lib/active_record/type/unsigned_integer.rb +15 -0
- data/lib/active_record/type/value.rb +110 -0
- data/lib/active_record/type.rb +23 -0
- data/lib/active_record/validations/associated.rb +5 -3
- data/lib/active_record/validations/presence.rb +5 -3
- data/lib/active_record/validations/uniqueness.rb +24 -20
- data/lib/active_record/validations.rb +25 -19
- data/lib/active_record.rb +5 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +8 -4
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb +1 -1
- metadata +66 -11
- data/lib/active_record/connection_adapters/postgresql/cast.rb +0 -168
@@ -39,7 +39,7 @@ module ActiveRecord
|
|
39
39
|
|
40
40
|
class PendingMigrationError < MigrationError#:nodoc:
|
41
41
|
def initialize
|
42
|
-
if defined?(Rails)
|
42
|
+
if defined?(Rails.env)
|
43
43
|
super("Migrations are pending. To resolve this issue, run:\n\n\tbin/rake db:migrate RAILS_ENV=#{::Rails.env}")
|
44
44
|
else
|
45
45
|
super("Migrations are pending. To resolve this issue, run:\n\n\tbin/rake db:migrate")
|
@@ -161,21 +161,14 @@ module ActiveRecord
|
|
161
161
|
# in the <tt>db/migrate/</tt> directory where <tt>timestamp</tt> is the
|
162
162
|
# UTC formatted date and time that the migration was generated.
|
163
163
|
#
|
164
|
-
# You may then edit the <tt>up</tt> and <tt>down</tt> methods of
|
165
|
-
# MyNewMigration.
|
166
|
-
#
|
167
164
|
# There is a special syntactic shortcut to generate migrations that add fields to a table.
|
168
165
|
#
|
169
166
|
# rails generate migration add_fieldname_to_tablename fieldname:string
|
170
167
|
#
|
171
168
|
# This will generate the file <tt>timestamp_add_fieldname_to_tablename</tt>, which will look like this:
|
172
169
|
# class AddFieldnameToTablename < ActiveRecord::Migration
|
173
|
-
# def
|
174
|
-
# add_column :tablenames, :
|
175
|
-
# end
|
176
|
-
#
|
177
|
-
# def down
|
178
|
-
# remove_column :tablenames, :fieldname
|
170
|
+
# def change
|
171
|
+
# add_column :tablenames, :field, :string
|
179
172
|
# end
|
180
173
|
# end
|
181
174
|
#
|
@@ -188,14 +181,17 @@ module ActiveRecord
|
|
188
181
|
#
|
189
182
|
# To roll the database back to a previous migration version, use
|
190
183
|
# <tt>rake db:migrate VERSION=X</tt> where <tt>X</tt> is the version to which
|
191
|
-
# you wish to downgrade.
|
192
|
-
# <tt>
|
193
|
-
#
|
184
|
+
# you wish to downgrade. Alternatively, you can also use the STEP option if you
|
185
|
+
# wish to rollback last few migrations. <tt>rake db:migrate STEP=2</tt> will rollback
|
186
|
+
# the latest two migrations.
|
187
|
+
#
|
188
|
+
# If any of the migrations throw an <tt>ActiveRecord::IrreversibleMigration</tt> exception,
|
189
|
+
# that step will fail and you'll have some manual work to do.
|
194
190
|
#
|
195
191
|
# == Database support
|
196
192
|
#
|
197
193
|
# Migrations are currently supported in MySQL, PostgreSQL, SQLite,
|
198
|
-
# SQL Server,
|
194
|
+
# SQL Server, and Oracle (all supported databases except DB2).
|
199
195
|
#
|
200
196
|
# == More examples
|
201
197
|
#
|
@@ -311,9 +307,8 @@ module ActiveRecord
|
|
311
307
|
#
|
312
308
|
# == Reversible Migrations
|
313
309
|
#
|
314
|
-
# Starting with Rails 3.1, you will be able to define reversible migrations.
|
315
310
|
# Reversible migrations are migrations that know how to go +down+ for you.
|
316
|
-
# You simply supply the +up+ logic, and the Migration system
|
311
|
+
# You simply supply the +up+ logic, and the Migration system figures out
|
317
312
|
# how to execute the down commands for you.
|
318
313
|
#
|
319
314
|
# To define a reversible migration, define the +change+ method in your
|
@@ -372,13 +367,21 @@ module ActiveRecord
|
|
372
367
|
end
|
373
368
|
|
374
369
|
def call(env)
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
370
|
+
if connection.supports_migrations?
|
371
|
+
mtime = ActiveRecord::Migrator.last_migration.mtime.to_i
|
372
|
+
if @last_check < mtime
|
373
|
+
ActiveRecord::Migration.check_pending!(connection)
|
374
|
+
@last_check = mtime
|
375
|
+
end
|
379
376
|
end
|
380
377
|
@app.call(env)
|
381
378
|
end
|
379
|
+
|
380
|
+
private
|
381
|
+
|
382
|
+
def connection
|
383
|
+
ActiveRecord::Base.connection
|
384
|
+
end
|
382
385
|
end
|
383
386
|
|
384
387
|
class << self
|
@@ -390,8 +393,15 @@ module ActiveRecord
|
|
390
393
|
end
|
391
394
|
|
392
395
|
def load_schema_if_pending!
|
393
|
-
if ActiveRecord::Migrator.needs_migration?
|
394
|
-
|
396
|
+
if ActiveRecord::Migrator.needs_migration? || !ActiveRecord::Migrator.any_migrations?
|
397
|
+
# Roundrip to Rake to allow plugins to hook into database initialization.
|
398
|
+
FileUtils.cd Rails.root do
|
399
|
+
current_config = Base.connection_config
|
400
|
+
Base.clear_all_connections!
|
401
|
+
system("bin/rake db:test:prepare")
|
402
|
+
# Establish a new connection, the old database may be gone (db:test:prepare uses purge)
|
403
|
+
Base.establish_connection(current_config)
|
404
|
+
end
|
395
405
|
check_pending!
|
396
406
|
end
|
397
407
|
end
|
@@ -410,7 +420,10 @@ module ActiveRecord
|
|
410
420
|
new.migrate direction
|
411
421
|
end
|
412
422
|
|
413
|
-
# Disable
|
423
|
+
# Disable the transaction wrapping this migration.
|
424
|
+
# You can still create your own transactions even after calling #disable_ddl_transaction!
|
425
|
+
#
|
426
|
+
# For more details read the {"Transactional Migrations" section above}[rdoc-ref:Migration].
|
414
427
|
def disable_ddl_transaction!
|
415
428
|
@disable_ddl_transaction = true
|
416
429
|
end
|
@@ -642,7 +655,10 @@ module ActiveRecord
|
|
642
655
|
unless @connection.respond_to? :revert
|
643
656
|
unless arguments.empty? || [:execute, :enable_extension, :disable_extension].include?(method)
|
644
657
|
arguments[0] = proper_table_name(arguments.first, table_name_options)
|
645
|
-
|
658
|
+
if [:rename_table, :add_foreign_key].include?(method) ||
|
659
|
+
(method == :remove_foreign_key && !arguments.second.is_a?(Hash))
|
660
|
+
arguments[1] = proper_table_name(arguments.second, table_name_options)
|
661
|
+
end
|
646
662
|
end
|
647
663
|
end
|
648
664
|
return super unless connection.respond_to?(method)
|
@@ -804,22 +820,22 @@ module ActiveRecord
|
|
804
820
|
migrations = migrations(migrations_paths)
|
805
821
|
migrations.select! { |m| yield m } if block_given?
|
806
822
|
|
807
|
-
|
823
|
+
new(:up, migrations, target_version).migrate
|
808
824
|
end
|
809
825
|
|
810
826
|
def down(migrations_paths, target_version = nil, &block)
|
811
827
|
migrations = migrations(migrations_paths)
|
812
828
|
migrations.select! { |m| yield m } if block_given?
|
813
829
|
|
814
|
-
|
830
|
+
new(:down, migrations, target_version).migrate
|
815
831
|
end
|
816
832
|
|
817
833
|
def run(direction, migrations_paths, target_version)
|
818
|
-
|
834
|
+
new(direction, migrations(migrations_paths), target_version).run
|
819
835
|
end
|
820
836
|
|
821
837
|
def open(migrations_paths)
|
822
|
-
|
838
|
+
new(:up, migrations(migrations_paths), nil)
|
823
839
|
end
|
824
840
|
|
825
841
|
def schema_migrations_table_name
|
@@ -842,6 +858,10 @@ module ActiveRecord
|
|
842
858
|
(migrations(migrations_paths).collect(&:version) - get_all_versions(connection)).size > 0
|
843
859
|
end
|
844
860
|
|
861
|
+
def any_migrations?
|
862
|
+
migrations(migrations_paths).any?
|
863
|
+
end
|
864
|
+
|
845
865
|
def last_version
|
846
866
|
last_migration.version
|
847
867
|
end
|
@@ -850,19 +870,6 @@ module ActiveRecord
|
|
850
870
|
migrations(migrations_paths).last || NullMigration.new
|
851
871
|
end
|
852
872
|
|
853
|
-
def proper_table_name(name, options = {})
|
854
|
-
ActiveSupport::Deprecation.warn "ActiveRecord::Migrator.proper_table_name is deprecated and will be removed in Rails 4.2. Use the proper_table_name instance method on ActiveRecord::Migration instead"
|
855
|
-
options = {
|
856
|
-
table_name_prefix: ActiveRecord::Base.table_name_prefix,
|
857
|
-
table_name_suffix: ActiveRecord::Base.table_name_suffix
|
858
|
-
}.merge(options)
|
859
|
-
if name.respond_to? :table_name
|
860
|
-
name.table_name
|
861
|
-
else
|
862
|
-
"#{options[:table_name_prefix]}#{name}#{options[:table_name_suffix]}"
|
863
|
-
end
|
864
|
-
end
|
865
|
-
|
866
873
|
def migrations_paths
|
867
874
|
@migrations_paths ||= ['db/migrate']
|
868
875
|
# just to not break things if someone uses: migration_path = some_string
|
@@ -873,14 +880,15 @@ module ActiveRecord
|
|
873
880
|
migrations_paths.first
|
874
881
|
end
|
875
882
|
|
883
|
+
def parse_migration_filename(filename) # :nodoc:
|
884
|
+
File.basename(filename).scan(/\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/).first
|
885
|
+
end
|
886
|
+
|
876
887
|
def migrations(paths)
|
877
888
|
paths = Array(paths)
|
878
889
|
|
879
|
-
|
880
|
-
|
881
|
-
migrations = files.map do |file|
|
882
|
-
version, name, scope = file.scan(/([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/).first
|
883
|
-
|
890
|
+
migrations = migration_files(paths).map do |file|
|
891
|
+
version, name, scope = parse_migration_filename(file)
|
884
892
|
raise IllegalMigrationNameError.new(file) unless version
|
885
893
|
version = version.to_i
|
886
894
|
name = name.camelize
|
@@ -891,10 +899,34 @@ module ActiveRecord
|
|
891
899
|
migrations.sort_by(&:version)
|
892
900
|
end
|
893
901
|
|
902
|
+
def migrations_status(paths)
|
903
|
+
paths = Array(paths)
|
904
|
+
|
905
|
+
db_list = ActiveRecord::SchemaMigration.normalized_versions
|
906
|
+
|
907
|
+
file_list = migration_files(paths).map do |file|
|
908
|
+
version, name, scope = parse_migration_filename(file)
|
909
|
+
raise IllegalMigrationNameError.new(file) unless version
|
910
|
+
version = ActiveRecord::SchemaMigration.normalize_migration_number(version)
|
911
|
+
status = db_list.delete(version) ? "up" : "down"
|
912
|
+
[status, version, (name + scope).humanize]
|
913
|
+
end.compact
|
914
|
+
|
915
|
+
db_list.map! do |version|
|
916
|
+
["up", version, "********** NO FILE **********"]
|
917
|
+
end
|
918
|
+
|
919
|
+
(db_list + file_list).sort_by { |_, version, _| version }
|
920
|
+
end
|
921
|
+
|
922
|
+
def migration_files(paths)
|
923
|
+
Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
|
924
|
+
end
|
925
|
+
|
894
926
|
private
|
895
927
|
|
896
928
|
def move(direction, migrations_paths, steps)
|
897
|
-
migrator =
|
929
|
+
migrator = new(direction, migrations(migrations_paths))
|
898
930
|
start_index = migrator.migrations.index(migrator.current_migration)
|
899
931
|
|
900
932
|
if start_index
|
@@ -29,6 +29,10 @@ module ActiveRecord
|
|
29
29
|
# :singleton-method:
|
30
30
|
# Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp",
|
31
31
|
# "people_basecamp"). By default, the suffix is the empty string.
|
32
|
+
#
|
33
|
+
# If you are organising your models within modules, you can add a suffix to the models within
|
34
|
+
# a namespace by defining a singleton method in the parent module called table_name_suffix which
|
35
|
+
# returns your chosen suffix.
|
32
36
|
class_attribute :table_name_suffix, instance_writer: false
|
33
37
|
self.table_name_suffix = ""
|
34
38
|
|
@@ -47,6 +51,19 @@ module ActiveRecord
|
|
47
51
|
self.pluralize_table_names = true
|
48
52
|
|
49
53
|
self.inheritance_column = 'type'
|
54
|
+
|
55
|
+
delegate :type_for_attribute, to: :class
|
56
|
+
end
|
57
|
+
|
58
|
+
# Derives the join table name for +first_table+ and +second_table+. The
|
59
|
+
# table names appear in alphabetical order. A common prefix is removed
|
60
|
+
# (useful for namespaced models like Music::Artist and Music::Record):
|
61
|
+
#
|
62
|
+
# artists, records => artists_records
|
63
|
+
# records, artists => artists_records
|
64
|
+
# music_artists, music_records => music_artists_records
|
65
|
+
def self.derive_join_table_name(first_table, second_table) # :nodoc:
|
66
|
+
[first_table.to_s, second_table.to_s].sort.join("\0").gsub(/^(.*_)(.+)\0\1(.+)/, '\1\2_\3').tr("\0", "_")
|
50
67
|
end
|
51
68
|
|
52
69
|
module ClassMethods
|
@@ -153,6 +170,10 @@ module ActiveRecord
|
|
153
170
|
(parents.detect{ |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
|
154
171
|
end
|
155
172
|
|
173
|
+
def full_table_name_suffix #:nodoc:
|
174
|
+
(parents.detect {|p| p.respond_to?(:table_name_suffix) } || self).table_name_suffix
|
175
|
+
end
|
176
|
+
|
156
177
|
# Defines the name of the table column which will store the class name on single-table
|
157
178
|
# inheritance situations.
|
158
179
|
#
|
@@ -190,7 +211,7 @@ module ActiveRecord
|
|
190
211
|
# given block. This is required for Oracle and is useful for any
|
191
212
|
# database which relies on sequences for primary key generation.
|
192
213
|
#
|
193
|
-
# If a sequence name is not explicitly set when using Oracle
|
214
|
+
# If a sequence name is not explicitly set when using Oracle,
|
194
215
|
# it will default to the commonly used pattern of: #{table_name}_seq
|
195
216
|
#
|
196
217
|
# If a sequence name is not explicitly set when using PostgreSQL, it
|
@@ -209,50 +230,29 @@ module ActiveRecord
|
|
209
230
|
connection.schema_cache.table_exists?(table_name)
|
210
231
|
end
|
211
232
|
|
212
|
-
|
213
|
-
|
214
|
-
@columns ||= connection.schema_cache.columns(table_name).map do |col|
|
215
|
-
col = col.dup
|
216
|
-
col.primary = (col.name == primary_key)
|
217
|
-
col
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
# Returns a hash of column objects for the table associated with this class.
|
222
|
-
def columns_hash
|
223
|
-
@columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
|
233
|
+
def attributes_builder # :nodoc:
|
234
|
+
@attributes_builder ||= AttributeSet::Builder.new(column_types, primary_key)
|
224
235
|
end
|
225
236
|
|
226
237
|
def column_types # :nodoc:
|
227
|
-
@column_types ||=
|
228
|
-
|
229
|
-
|
230
|
-
def decorate_columns(columns_hash) # :nodoc:
|
231
|
-
return if columns_hash.empty?
|
232
|
-
|
233
|
-
@serialized_column_names ||= self.columns_hash.keys.find_all do |name|
|
234
|
-
serialized_attributes.key?(name)
|
235
|
-
end
|
236
|
-
|
237
|
-
@serialized_column_names.each do |name|
|
238
|
-
columns_hash[name] = AttributeMethods::Serialization::Type.new(columns_hash[name])
|
239
|
-
end
|
240
|
-
|
241
|
-
@time_zone_column_names ||= self.columns_hash.find_all do |name, col|
|
242
|
-
create_time_zone_conversion_attribute?(name, col)
|
243
|
-
end.map!(&:first)
|
244
|
-
|
245
|
-
@time_zone_column_names.each do |name|
|
246
|
-
columns_hash[name] = AttributeMethods::TimeZoneConversion::Type.new(columns_hash[name])
|
238
|
+
@column_types ||= columns_hash.transform_values(&:cast_type).tap do |h|
|
239
|
+
h.default = Type::Value.new
|
247
240
|
end
|
241
|
+
end
|
248
242
|
|
249
|
-
|
243
|
+
def type_for_attribute(attr_name) # :nodoc:
|
244
|
+
column_types[attr_name]
|
250
245
|
end
|
251
246
|
|
252
247
|
# Returns a hash where the keys are column names and the values are
|
253
248
|
# default values when instantiating the AR object for this table.
|
254
249
|
def column_defaults
|
255
|
-
|
250
|
+
_default_attributes.dup.to_hash
|
251
|
+
end
|
252
|
+
|
253
|
+
def _default_attributes # :nodoc:
|
254
|
+
@default_attributes ||= attributes_builder.build_from_database(
|
255
|
+
raw_default_values)
|
256
256
|
end
|
257
257
|
|
258
258
|
# Returns an array of column names as strings.
|
@@ -263,7 +263,7 @@ module ActiveRecord
|
|
263
263
|
# Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
|
264
264
|
# and columns used for single table inheritance have been removed.
|
265
265
|
def content_columns
|
266
|
-
@content_columns ||= columns.reject { |c| c.
|
266
|
+
@content_columns ||= columns.reject { |c| c.name == primary_key || c.name =~ /(_id|_count)$/ || c.name == inheritance_column }
|
267
267
|
end
|
268
268
|
|
269
269
|
# Resets all the cached information about columns, which will cause them
|
@@ -295,28 +295,17 @@ module ActiveRecord
|
|
295
295
|
def reset_column_information
|
296
296
|
connection.clear_cache!
|
297
297
|
undefine_attribute_methods
|
298
|
-
connection.schema_cache.clear_table_cache!(table_name)
|
299
|
-
|
300
|
-
@arel_engine
|
301
|
-
@
|
302
|
-
@
|
303
|
-
@
|
304
|
-
@
|
305
|
-
@
|
306
|
-
@
|
307
|
-
@dynamic_methods_hash = nil
|
308
|
-
@inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column
|
309
|
-
@relation = nil
|
310
|
-
@serialized_column_names = nil
|
311
|
-
@time_zone_column_names = nil
|
312
|
-
@cached_time_zone = nil
|
313
|
-
end
|
298
|
+
connection.schema_cache.clear_table_cache!(table_name)
|
299
|
+
|
300
|
+
@arel_engine = nil
|
301
|
+
@column_names = nil
|
302
|
+
@column_types = nil
|
303
|
+
@content_columns = nil
|
304
|
+
@default_attributes = nil
|
305
|
+
@inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column
|
306
|
+
@relation = nil
|
314
307
|
|
315
|
-
|
316
|
-
# attributes when they are initialized. (e.g. attribute
|
317
|
-
# serialization)
|
318
|
-
def initialize_attributes(attributes, options = {}) #:nodoc:
|
319
|
-
attributes
|
308
|
+
initialize_find_by_cache
|
320
309
|
end
|
321
310
|
|
322
311
|
private
|
@@ -337,12 +326,17 @@ module ActiveRecord
|
|
337
326
|
contained = contained.singularize if parent.pluralize_table_names
|
338
327
|
contained += '_'
|
339
328
|
end
|
340
|
-
|
329
|
+
|
330
|
+
"#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{full_table_name_suffix}"
|
341
331
|
else
|
342
332
|
# STI subclasses always use their superclass' table.
|
343
333
|
base.table_name
|
344
334
|
end
|
345
335
|
end
|
336
|
+
|
337
|
+
def raw_default_values
|
338
|
+
columns_hash.transform_values(&:default)
|
339
|
+
end
|
346
340
|
end
|
347
341
|
end
|
348
342
|
end
|
@@ -307,7 +307,7 @@ module ActiveRecord
|
|
307
307
|
attr_names.each do |association_name|
|
308
308
|
if reflection = _reflect_on_association(association_name)
|
309
309
|
reflection.autosave = true
|
310
|
-
|
310
|
+
define_autosave_validation_callbacks(reflection)
|
311
311
|
|
312
312
|
nested_attributes_options = self.nested_attributes_options.dup
|
313
313
|
nested_attributes_options[association_name.to_sym] = options
|
@@ -485,10 +485,10 @@ module ActiveRecord
|
|
485
485
|
end
|
486
486
|
|
487
487
|
# Takes in a limit and checks if the attributes_collection has too many
|
488
|
-
# records.
|
489
|
-
# number-like
|
488
|
+
# records. It accepts limit in the form of symbol, proc, or
|
489
|
+
# number-like object (anything that can be compared with an integer).
|
490
490
|
#
|
491
|
-
#
|
491
|
+
# Raises TooManyRecords error if the attributes_collection is
|
492
492
|
# larger than the limit.
|
493
493
|
def check_record_limit!(limit, attributes_collection)
|
494
494
|
if limit
|
@@ -516,14 +516,14 @@ module ActiveRecord
|
|
516
516
|
|
517
517
|
# Determines if a hash contains a truthy _destroy key.
|
518
518
|
def has_destroy_flag?(hash)
|
519
|
-
|
519
|
+
Type::Boolean.new.type_cast_from_user(hash['_destroy'])
|
520
520
|
end
|
521
521
|
|
522
|
-
# Determines if a new record should be
|
522
|
+
# Determines if a new record should be rejected by checking
|
523
523
|
# has_destroy_flag? or if a <tt>:reject_if</tt> proc exists for this
|
524
524
|
# association and evaluates to +true+.
|
525
525
|
def reject_new_record?(association_name, attributes)
|
526
|
-
|
526
|
+
will_be_destroyed?(association_name, attributes) || call_reject_if(association_name, attributes)
|
527
527
|
end
|
528
528
|
|
529
529
|
# Determines if a record with the particular +attributes+ should be
|
@@ -532,7 +532,8 @@ module ActiveRecord
|
|
532
532
|
#
|
533
533
|
# Returns false if there is a +destroy_flag+ on the attributes.
|
534
534
|
def call_reject_if(association_name, attributes)
|
535
|
-
return false if
|
535
|
+
return false if will_be_destroyed?(association_name, attributes)
|
536
|
+
|
536
537
|
case callback = self.nested_attributes_options[association_name][:reject_if]
|
537
538
|
when Symbol
|
538
539
|
method(callback).arity == 0 ? send(callback) : send(callback, attributes)
|
@@ -541,6 +542,15 @@ module ActiveRecord
|
|
541
542
|
end
|
542
543
|
end
|
543
544
|
|
545
|
+
# Only take into account the destroy flag if <tt>:allow_destroy</tt> is true
|
546
|
+
def will_be_destroyed?(association_name, attributes)
|
547
|
+
allow_destroy?(association_name) && has_destroy_flag?(attributes)
|
548
|
+
end
|
549
|
+
|
550
|
+
def allow_destroy?(association_name)
|
551
|
+
self.nested_attributes_options[association_name][:allow_destroy]
|
552
|
+
end
|
553
|
+
|
544
554
|
def raise_nested_attributes_record_not_found!(association_name, record_id)
|
545
555
|
raise RecordNotFound, "Couldn't find #{self.class._reflect_on_association(association_name).klass.name} with ID=#{record_id} for #{self.class.name} with ID=#{id}"
|
546
556
|
end
|