activerecord 3.2.22.4 → 4.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +2799 -617
 - data/MIT-LICENSE +1 -1
 - data/README.rdoc +23 -32
 - data/examples/performance.rb +1 -1
 - data/lib/active_record/aggregations.rb +40 -34
 - data/lib/active_record/association_relation.rb +22 -0
 - data/lib/active_record/associations/alias_tracker.rb +4 -2
 - data/lib/active_record/associations/association.rb +60 -46
 - data/lib/active_record/associations/association_scope.rb +46 -40
 - data/lib/active_record/associations/belongs_to_association.rb +17 -4
 - data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
 - data/lib/active_record/associations/builder/association.rb +81 -28
 - data/lib/active_record/associations/builder/belongs_to.rb +73 -56
 - data/lib/active_record/associations/builder/collection_association.rb +54 -40
 - data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +23 -41
 - data/lib/active_record/associations/builder/has_many.rb +8 -64
 - data/lib/active_record/associations/builder/has_one.rb +13 -50
 - data/lib/active_record/associations/builder/singular_association.rb +13 -13
 - data/lib/active_record/associations/collection_association.rb +130 -96
 - data/lib/active_record/associations/collection_proxy.rb +916 -63
 - data/lib/active_record/associations/has_and_belongs_to_many_association.rb +15 -13
 - data/lib/active_record/associations/has_many_association.rb +35 -8
 - data/lib/active_record/associations/has_many_through_association.rb +37 -17
 - data/lib/active_record/associations/has_one_association.rb +42 -19
 - data/lib/active_record/associations/has_one_through_association.rb +1 -1
 - data/lib/active_record/associations/join_dependency/join_association.rb +39 -22
 - data/lib/active_record/associations/join_dependency/join_base.rb +2 -2
 - data/lib/active_record/associations/join_dependency/join_part.rb +21 -8
 - data/lib/active_record/associations/join_dependency.rb +30 -9
 - data/lib/active_record/associations/join_helper.rb +1 -11
 - data/lib/active_record/associations/preloader/association.rb +29 -33
 - data/lib/active_record/associations/preloader/collection_association.rb +1 -1
 - data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +2 -2
 - data/lib/active_record/associations/preloader/has_many_through.rb +6 -2
 - data/lib/active_record/associations/preloader/has_one.rb +1 -1
 - data/lib/active_record/associations/preloader/through_association.rb +13 -17
 - data/lib/active_record/associations/preloader.rb +20 -43
 - data/lib/active_record/associations/singular_association.rb +11 -11
 - data/lib/active_record/associations/through_association.rb +3 -3
 - data/lib/active_record/associations.rb +223 -282
 - data/lib/active_record/attribute_assignment.rb +134 -154
 - data/lib/active_record/attribute_methods/before_type_cast.rb +44 -5
 - data/lib/active_record/attribute_methods/dirty.rb +36 -29
 - data/lib/active_record/attribute_methods/primary_key.rb +45 -31
 - data/lib/active_record/attribute_methods/query.rb +5 -4
 - data/lib/active_record/attribute_methods/read.rb +67 -90
 - data/lib/active_record/attribute_methods/serialization.rb +133 -70
 - data/lib/active_record/attribute_methods/time_zone_conversion.rb +51 -45
 - data/lib/active_record/attribute_methods/write.rb +34 -39
 - data/lib/active_record/attribute_methods.rb +268 -108
 - data/lib/active_record/autosave_association.rb +80 -73
 - data/lib/active_record/base.rb +54 -451
 - data/lib/active_record/callbacks.rb +60 -22
 - data/lib/active_record/coders/yaml_column.rb +18 -21
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +347 -197
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +146 -138
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +25 -19
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +19 -3
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +151 -142
 - data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +70 -0
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +499 -217
 - data/lib/active_record/connection_adapters/abstract/transaction.rb +208 -0
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +209 -44
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +169 -61
 - data/lib/active_record/connection_adapters/column.rb +67 -36
 - data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
 - data/lib/active_record/connection_adapters/mysql2_adapter.rb +28 -29
 - data/lib/active_record/connection_adapters/mysql_adapter.rb +200 -73
 - data/lib/active_record/connection_adapters/postgresql/array_parser.rb +98 -0
 - data/lib/active_record/connection_adapters/postgresql/cast.rb +160 -0
 - data/lib/active_record/connection_adapters/postgresql/database_statements.rb +240 -0
 - data/lib/active_record/connection_adapters/postgresql/oid.rb +374 -0
 - data/lib/active_record/connection_adapters/postgresql/quoting.rb +183 -0
 - data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +508 -0
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +544 -899
 - data/lib/active_record/connection_adapters/schema_cache.rb +76 -16
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +595 -16
 - data/lib/active_record/connection_handling.rb +98 -0
 - data/lib/active_record/core.rb +472 -0
 - data/lib/active_record/counter_cache.rb +107 -108
 - data/lib/active_record/dynamic_matchers.rb +115 -63
 - data/lib/active_record/errors.rb +36 -18
 - data/lib/active_record/explain.rb +15 -63
 - data/lib/active_record/explain_registry.rb +30 -0
 - data/lib/active_record/explain_subscriber.rb +8 -4
 - data/lib/active_record/fixture_set/file.rb +55 -0
 - data/lib/active_record/fixtures.rb +159 -155
 - data/lib/active_record/inheritance.rb +93 -59
 - data/lib/active_record/integration.rb +8 -8
 - data/lib/active_record/locale/en.yml +8 -1
 - data/lib/active_record/locking/optimistic.rb +39 -43
 - data/lib/active_record/locking/pessimistic.rb +4 -4
 - data/lib/active_record/log_subscriber.rb +19 -9
 - data/lib/active_record/migration/command_recorder.rb +102 -33
 - data/lib/active_record/migration/join_table.rb +15 -0
 - data/lib/active_record/migration.rb +411 -173
 - data/lib/active_record/model_schema.rb +81 -94
 - data/lib/active_record/nested_attributes.rb +173 -131
 - data/lib/active_record/null_relation.rb +67 -0
 - data/lib/active_record/persistence.rb +254 -106
 - data/lib/active_record/query_cache.rb +18 -36
 - data/lib/active_record/querying.rb +19 -15
 - data/lib/active_record/railtie.rb +113 -38
 - data/lib/active_record/railties/console_sandbox.rb +3 -4
 - data/lib/active_record/railties/controller_runtime.rb +4 -3
 - data/lib/active_record/railties/databases.rake +115 -368
 - data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
 - data/lib/active_record/readonly_attributes.rb +7 -3
 - data/lib/active_record/reflection.rb +110 -61
 - data/lib/active_record/relation/batches.rb +29 -29
 - data/lib/active_record/relation/calculations.rb +155 -125
 - data/lib/active_record/relation/delegation.rb +94 -18
 - data/lib/active_record/relation/finder_methods.rb +151 -203
 - data/lib/active_record/relation/merger.rb +188 -0
 - data/lib/active_record/relation/predicate_builder.rb +85 -42
 - data/lib/active_record/relation/query_methods.rb +793 -146
 - data/lib/active_record/relation/spawn_methods.rb +43 -150
 - data/lib/active_record/relation.rb +293 -173
 - data/lib/active_record/result.rb +48 -7
 - data/lib/active_record/runtime_registry.rb +17 -0
 - data/lib/active_record/sanitization.rb +41 -54
 - data/lib/active_record/schema.rb +19 -12
 - data/lib/active_record/schema_dumper.rb +41 -41
 - data/lib/active_record/schema_migration.rb +46 -0
 - data/lib/active_record/scoping/default.rb +56 -52
 - data/lib/active_record/scoping/named.rb +78 -103
 - data/lib/active_record/scoping.rb +54 -124
 - data/lib/active_record/serialization.rb +6 -2
 - data/lib/active_record/serializers/xml_serializer.rb +9 -15
 - data/lib/active_record/statement_cache.rb +26 -0
 - data/lib/active_record/store.rb +131 -15
 - data/lib/active_record/tasks/database_tasks.rb +204 -0
 - data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
 - data/lib/active_record/tasks/mysql_database_tasks.rb +144 -0
 - data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
 - data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
 - data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
 - data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
 - data/lib/active_record/test_case.rb +67 -38
 - data/lib/active_record/timestamp.rb +16 -11
 - data/lib/active_record/transactions.rb +73 -51
 - data/lib/active_record/validations/associated.rb +19 -13
 - data/lib/active_record/validations/presence.rb +65 -0
 - data/lib/active_record/validations/uniqueness.rb +110 -57
 - data/lib/active_record/validations.rb +18 -17
 - data/lib/active_record/version.rb +7 -6
 - data/lib/active_record.rb +63 -45
 - data/lib/rails/generators/active_record/migration/migration_generator.rb +45 -8
 - data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +4 -0
 - data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
 - data/lib/rails/generators/active_record/model/model_generator.rb +5 -4
 - data/lib/rails/generators/active_record/model/templates/model.rb +4 -6
 - data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
 - data/lib/rails/generators/active_record.rb +3 -5
 - metadata +43 -29
 - data/examples/associations.png +0 -0
 - data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
 - data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
 - data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
 - 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/session_store.rb +0 -360
 - data/lib/rails/generators/active_record/migration.rb +0 -15
 - 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,10 +1,11 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require ' 
     | 
| 
       2 
     | 
    
         
            -
            require 'active_support/deprecation/reporting'
         
     | 
| 
      
 1 
     | 
    
         
            +
            require 'active_record/migration/join_table'
         
     | 
| 
       3 
2 
     | 
    
         | 
| 
       4 
3 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       5 
4 
     | 
    
         
             
              module ConnectionAdapters # :nodoc:
         
     | 
| 
       6 
5 
     | 
    
         
             
                module SchemaStatements
         
     | 
| 
       7 
     | 
    
         
            -
                   
     | 
| 
      
 6 
     | 
    
         
            +
                  include ActiveRecord::Migration::JoinTable
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  # Returns a hash of mappings from the abstract data types to the native
         
     | 
| 
       8 
9 
     | 
    
         
             
                  # database types. See TableDefinition#column for details on the recognized
         
     | 
| 
       9 
10 
     | 
    
         
             
                  # abstract data types.
         
     | 
| 
       10 
11 
     | 
    
         
             
                  def native_database_types
         
     | 
| 
         @@ -13,13 +14,13 @@ module ActiveRecord 
     | 
|
| 
       13 
14 
     | 
    
         | 
| 
       14 
15 
     | 
    
         
             
                  # Truncates a table alias according to the limits of the current adapter.
         
     | 
| 
       15 
16 
     | 
    
         
             
                  def table_alias_for(table_name)
         
     | 
| 
       16 
     | 
    
         
            -
                    table_name[0...table_alias_length]. 
     | 
| 
      
 17 
     | 
    
         
            +
                    table_name[0...table_alias_length].tr('.', '_')
         
     | 
| 
       17 
18 
     | 
    
         
             
                  end
         
     | 
| 
       18 
19 
     | 
    
         | 
| 
       19 
20 
     | 
    
         
             
                  # Checks to see if the table +table_name+ exists on the database.
         
     | 
| 
       20 
21 
     | 
    
         
             
                  #
         
     | 
| 
       21 
     | 
    
         
            -
                  # === Example
         
     | 
| 
       22 
22 
     | 
    
         
             
                  #   table_exists?(:developers)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #
         
     | 
| 
       23 
24 
     | 
    
         
             
                  def table_exists?(table_name)
         
     | 
| 
       24 
25 
     | 
    
         
             
                    tables.include?(table_name.to_s)
         
     | 
| 
       25 
26 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -29,20 +30,20 @@ module ActiveRecord 
     | 
|
| 
       29 
30 
     | 
    
         | 
| 
       30 
31 
     | 
    
         
             
                  # Checks to see if an index exists on a table for a given index definition.
         
     | 
| 
       31 
32 
     | 
    
         
             
                  #
         
     | 
| 
       32 
     | 
    
         
            -
                  #  
     | 
| 
       33 
     | 
    
         
            -
                  # 
     | 
| 
       34 
     | 
    
         
            -
                  #  index_exists?(:suppliers, :company_id)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  #   # Check an index exists
         
     | 
| 
      
 34 
     | 
    
         
            +
                  #   index_exists?(:suppliers, :company_id)
         
     | 
| 
       35 
35 
     | 
    
         
             
                  #
         
     | 
| 
       36 
     | 
    
         
            -
                  # 
     | 
| 
       37 
     | 
    
         
            -
                  # 
     | 
| 
      
 36 
     | 
    
         
            +
                  #   # Check an index on multiple columns exists
         
     | 
| 
      
 37 
     | 
    
         
            +
                  #   index_exists?(:suppliers, [:company_id, :company_type])
         
     | 
| 
       38 
38 
     | 
    
         
             
                  #
         
     | 
| 
       39 
     | 
    
         
            -
                  # 
     | 
| 
       40 
     | 
    
         
            -
                  # 
     | 
| 
      
 39 
     | 
    
         
            +
                  #   # Check a unique index exists
         
     | 
| 
      
 40 
     | 
    
         
            +
                  #   index_exists?(:suppliers, :company_id, unique: true)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  #
         
     | 
| 
      
 42 
     | 
    
         
            +
                  #   # Check an index with a custom name exists
         
     | 
| 
      
 43 
     | 
    
         
            +
                  #   index_exists?(:suppliers, :company_id, name: "idx_company_id"
         
     | 
| 
       41 
44 
     | 
    
         
             
                  #
         
     | 
| 
       42 
     | 
    
         
            -
                  #  # Check an index with a custom name exists
         
     | 
| 
       43 
     | 
    
         
            -
                  #  index_exists?(:suppliers, :company_id, :name => "idx_company_id"
         
     | 
| 
       44 
45 
     | 
    
         
             
                  def index_exists?(table_name, column_name, options = {})
         
     | 
| 
       45 
     | 
    
         
            -
                    column_names = Array 
     | 
| 
      
 46 
     | 
    
         
            +
                    column_names = Array(column_name)
         
     | 
| 
       46 
47 
     | 
    
         
             
                    index_name = options.key?(:name) ? options[:name].to_s : index_name(table_name, :column => column_names)
         
     | 
| 
       47 
48 
     | 
    
         
             
                    if options[:unique]
         
     | 
| 
       48 
49 
     | 
    
         
             
                      indexes(table_name).any?{ |i| i.unique && i.name == index_name }
         
     | 
| 
         @@ -53,25 +54,30 @@ module ActiveRecord 
     | 
|
| 
       53 
54 
     | 
    
         | 
| 
       54 
55 
     | 
    
         
             
                  # Returns an array of Column objects for the table specified by +table_name+.
         
     | 
| 
       55 
56 
     | 
    
         
             
                  # See the concrete implementation for details on the expected parameter values.
         
     | 
| 
       56 
     | 
    
         
            -
                  def columns(table_name 
     | 
| 
      
 57 
     | 
    
         
            +
                  def columns(table_name) end
         
     | 
| 
       57 
58 
     | 
    
         | 
| 
       58 
59 
     | 
    
         
             
                  # Checks to see if a column exists in a given table.
         
     | 
| 
       59 
60 
     | 
    
         
             
                  #
         
     | 
| 
       60 
     | 
    
         
            -
                  #  
     | 
| 
       61 
     | 
    
         
            -
                  # 
     | 
| 
       62 
     | 
    
         
            -
                  # 
     | 
| 
      
 61 
     | 
    
         
            +
                  #   # Check a column exists
         
     | 
| 
      
 62 
     | 
    
         
            +
                  #   column_exists?(:suppliers, :name)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  #
         
     | 
| 
      
 64 
     | 
    
         
            +
                  #   # Check a column exists of a particular type
         
     | 
| 
      
 65 
     | 
    
         
            +
                  #   column_exists?(:suppliers, :name, :string)
         
     | 
| 
       63 
66 
     | 
    
         
             
                  #
         
     | 
| 
       64 
     | 
    
         
            -
                  # 
     | 
| 
       65 
     | 
    
         
            -
                  # 
     | 
| 
      
 67 
     | 
    
         
            +
                  #   # Check a column exists with a specific definition
         
     | 
| 
      
 68 
     | 
    
         
            +
                  #   column_exists?(:suppliers, :name, :string, limit: 100)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  #   column_exists?(:suppliers, :name, :string, default: 'default')
         
     | 
| 
      
 70 
     | 
    
         
            +
                  #   column_exists?(:suppliers, :name, :string, null: false)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  #   column_exists?(:suppliers, :tax, :decimal, precision: 8, scale: 2)
         
     | 
| 
       66 
72 
     | 
    
         
             
                  #
         
     | 
| 
       67 
     | 
    
         
            -
                  #  # Check a column exists with a specific definition
         
     | 
| 
       68 
     | 
    
         
            -
                  #  column_exists?(:suppliers, :name, :string, :limit => 100)
         
     | 
| 
       69 
73 
     | 
    
         
             
                  def column_exists?(table_name, column_name, type = nil, options = {})
         
     | 
| 
       70 
74 
     | 
    
         
             
                    columns(table_name).any?{ |c| c.name == column_name.to_s &&
         
     | 
| 
       71 
     | 
    
         
            -
                                                  (!type 
     | 
| 
       72 
     | 
    
         
            -
                                                  (!options 
     | 
| 
       73 
     | 
    
         
            -
                                                  (!options 
     | 
| 
       74 
     | 
    
         
            -
                                                  (!options 
     | 
| 
      
 75 
     | 
    
         
            +
                                                  (!type                     || c.type == type) &&
         
     | 
| 
      
 76 
     | 
    
         
            +
                                                  (!options.key?(:limit)     || c.limit == options[:limit]) &&
         
     | 
| 
      
 77 
     | 
    
         
            +
                                                  (!options.key?(:precision) || c.precision == options[:precision]) &&
         
     | 
| 
      
 78 
     | 
    
         
            +
                                                  (!options.key?(:scale)     || c.scale == options[:scale]) &&
         
     | 
| 
      
 79 
     | 
    
         
            +
                                                  (!options.key?(:default)   || c.default == options[:default]) &&
         
     | 
| 
      
 80 
     | 
    
         
            +
                                                  (!options.key?(:null)      || c.null == options[:null]) }
         
     | 
| 
       75 
81 
     | 
    
         
             
                  end
         
     | 
| 
       76 
82 
     | 
    
         | 
| 
       77 
83 
     | 
    
         
             
                  # Creates a new table with the name +table_name+. +table_name+ may either
         
     | 
| 
         @@ -81,27 +87,30 @@ module ActiveRecord 
     | 
|
| 
       81 
87 
     | 
    
         
             
                  # form or the regular form, like this:
         
     | 
| 
       82 
88 
     | 
    
         
             
                  #
         
     | 
| 
       83 
89 
     | 
    
         
             
                  # === Block form
         
     | 
| 
       84 
     | 
    
         
            -
                  #  # create_table() passes a TableDefinition object to the block.
         
     | 
| 
       85 
     | 
    
         
            -
                  #  # This form will not only create the table, but also columns for the
         
     | 
| 
       86 
     | 
    
         
            -
                  #  # table.
         
     | 
| 
       87 
90 
     | 
    
         
             
                  #
         
     | 
| 
       88 
     | 
    
         
            -
                  # 
     | 
| 
       89 
     | 
    
         
            -
                  # 
     | 
| 
       90 
     | 
    
         
            -
                  # 
     | 
| 
       91 
     | 
    
         
            -
                  # 
     | 
| 
      
 91 
     | 
    
         
            +
                  #   # create_table() passes a TableDefinition object to the block.
         
     | 
| 
      
 92 
     | 
    
         
            +
                  #   # This form will not only create the table, but also columns for the
         
     | 
| 
      
 93 
     | 
    
         
            +
                  #   # table.
         
     | 
| 
      
 94 
     | 
    
         
            +
                  #
         
     | 
| 
      
 95 
     | 
    
         
            +
                  #   create_table(:suppliers) do |t|
         
     | 
| 
      
 96 
     | 
    
         
            +
                  #     t.column :name, :string, limit: 60
         
     | 
| 
      
 97 
     | 
    
         
            +
                  #     # Other fields here
         
     | 
| 
      
 98 
     | 
    
         
            +
                  #   end
         
     | 
| 
       92 
99 
     | 
    
         
             
                  #
         
     | 
| 
       93 
100 
     | 
    
         
             
                  # === Block form, with shorthand
         
     | 
| 
       94 
     | 
    
         
            -
                  # 
     | 
| 
       95 
     | 
    
         
            -
                  # 
     | 
| 
       96 
     | 
    
         
            -
                  # 
     | 
| 
       97 
     | 
    
         
            -
                  # 
     | 
| 
       98 
     | 
    
         
            -
                  # 
     | 
| 
      
 101 
     | 
    
         
            +
                  #
         
     | 
| 
      
 102 
     | 
    
         
            +
                  #   # You can also use the column types as method calls, rather than calling the column method.
         
     | 
| 
      
 103 
     | 
    
         
            +
                  #   create_table(:suppliers) do |t|
         
     | 
| 
      
 104 
     | 
    
         
            +
                  #     t.string :name, limit: 60
         
     | 
| 
      
 105 
     | 
    
         
            +
                  #     # Other fields here
         
     | 
| 
      
 106 
     | 
    
         
            +
                  #   end
         
     | 
| 
       99 
107 
     | 
    
         
             
                  #
         
     | 
| 
       100 
108 
     | 
    
         
             
                  # === Regular form
         
     | 
| 
       101 
     | 
    
         
            -
                  # 
     | 
| 
       102 
     | 
    
         
            -
                  # 
     | 
| 
       103 
     | 
    
         
            -
                  # 
     | 
| 
       104 
     | 
    
         
            -
                  # 
     | 
| 
      
 109 
     | 
    
         
            +
                  #
         
     | 
| 
      
 110 
     | 
    
         
            +
                  #   # Creates a table called 'suppliers' with no columns.
         
     | 
| 
      
 111 
     | 
    
         
            +
                  #   create_table(:suppliers)
         
     | 
| 
      
 112 
     | 
    
         
            +
                  #   # Add a column to 'suppliers'.
         
     | 
| 
      
 113 
     | 
    
         
            +
                  #   add_column(:suppliers, :name, :string, {limit: 60})
         
     | 
| 
       105 
114 
     | 
    
         
             
                  #
         
     | 
| 
       106 
115 
     | 
    
         
             
                  # The +options+ hash can include the following keys:
         
     | 
| 
       107 
116 
     | 
    
         
             
                  # [<tt>:id</tt>]
         
     | 
| 
         @@ -111,9 +120,9 @@ module ActiveRecord 
     | 
|
| 
       111 
120 
     | 
    
         
             
                  #   The name of the primary key, if one is to be added automatically.
         
     | 
| 
       112 
121 
     | 
    
         
             
                  #   Defaults to +id+. If <tt>:id</tt> is false this option is ignored.
         
     | 
| 
       113 
122 
     | 
    
         
             
                  #
         
     | 
| 
       114 
     | 
    
         
            -
                  #    
     | 
| 
       115 
     | 
    
         
            -
                  #    
     | 
| 
       116 
     | 
    
         
            -
                  #    
     | 
| 
      
 123 
     | 
    
         
            +
                  #   Note that Active Record models will automatically detect their
         
     | 
| 
      
 124 
     | 
    
         
            +
                  #   primary key. This can be avoided by using +self.primary_key=+ on the model
         
     | 
| 
      
 125 
     | 
    
         
            +
                  #   to define the key explicitly.
         
     | 
| 
       117 
126 
     | 
    
         
             
                  #
         
     | 
| 
       118 
127 
     | 
    
         
             
                  # [<tt>:options</tt>]
         
     | 
| 
       119 
128 
     | 
    
         
             
                  #   Any extra options you want appended to the table definition.
         
     | 
| 
         @@ -123,39 +132,54 @@ module ActiveRecord 
     | 
|
| 
       123 
132 
     | 
    
         
             
                  #   Set to true to drop the table before creating it.
         
     | 
| 
       124 
133 
     | 
    
         
             
                  #   Defaults to false.
         
     | 
| 
       125 
134 
     | 
    
         
             
                  #
         
     | 
| 
       126 
     | 
    
         
            -
                  # ===== Examples
         
     | 
| 
       127 
135 
     | 
    
         
             
                  # ====== Add a backend specific option to the generated SQL (MySQL)
         
     | 
| 
       128 
     | 
    
         
            -
                  # 
     | 
| 
      
 136 
     | 
    
         
            +
                  #
         
     | 
| 
      
 137 
     | 
    
         
            +
                  #   create_table(:suppliers, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8')
         
     | 
| 
      
 138 
     | 
    
         
            +
                  #
         
     | 
| 
       129 
139 
     | 
    
         
             
                  # generates:
         
     | 
| 
       130 
     | 
    
         
            -
                  # 
     | 
| 
       131 
     | 
    
         
            -
                  # 
     | 
| 
       132 
     | 
    
         
            -
                  # 
     | 
| 
      
 140 
     | 
    
         
            +
                  #
         
     | 
| 
      
 141 
     | 
    
         
            +
                  #   CREATE TABLE suppliers (
         
     | 
| 
      
 142 
     | 
    
         
            +
                  #     id int(11) DEFAULT NULL auto_increment PRIMARY KEY
         
     | 
| 
      
 143 
     | 
    
         
            +
                  #   ) ENGINE=InnoDB DEFAULT CHARSET=utf8
         
     | 
| 
       133 
144 
     | 
    
         
             
                  #
         
     | 
| 
       134 
145 
     | 
    
         
             
                  # ====== Rename the primary key column
         
     | 
| 
       135 
     | 
    
         
            -
                  # 
     | 
| 
       136 
     | 
    
         
            -
                  # 
     | 
| 
       137 
     | 
    
         
            -
                  # 
     | 
| 
      
 146 
     | 
    
         
            +
                  #
         
     | 
| 
      
 147 
     | 
    
         
            +
                  #   create_table(:objects, primary_key: 'guid') do |t|
         
     | 
| 
      
 148 
     | 
    
         
            +
                  #     t.column :name, :string, limit: 80
         
     | 
| 
      
 149 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 150 
     | 
    
         
            +
                  #
         
     | 
| 
       138 
151 
     | 
    
         
             
                  # generates:
         
     | 
| 
       139 
     | 
    
         
            -
                  # 
     | 
| 
       140 
     | 
    
         
            -
                  # 
     | 
| 
       141 
     | 
    
         
            -
                  # 
     | 
| 
       142 
     | 
    
         
            -
                  # 
     | 
| 
      
 152 
     | 
    
         
            +
                  #
         
     | 
| 
      
 153 
     | 
    
         
            +
                  #   CREATE TABLE objects (
         
     | 
| 
      
 154 
     | 
    
         
            +
                  #     guid int(11) DEFAULT NULL auto_increment PRIMARY KEY,
         
     | 
| 
      
 155 
     | 
    
         
            +
                  #     name varchar(80)
         
     | 
| 
      
 156 
     | 
    
         
            +
                  #   )
         
     | 
| 
       143 
157 
     | 
    
         
             
                  #
         
     | 
| 
       144 
158 
     | 
    
         
             
                  # ====== Do not add a primary key column
         
     | 
| 
       145 
     | 
    
         
            -
                  # 
     | 
| 
       146 
     | 
    
         
            -
                  # 
     | 
| 
       147 
     | 
    
         
            -
                  # 
     | 
| 
       148 
     | 
    
         
            -
                  # 
     | 
| 
      
 159 
     | 
    
         
            +
                  #
         
     | 
| 
      
 160 
     | 
    
         
            +
                  #   create_table(:categories_suppliers, id: false) do |t|
         
     | 
| 
      
 161 
     | 
    
         
            +
                  #     t.column :category_id, :integer
         
     | 
| 
      
 162 
     | 
    
         
            +
                  #     t.column :supplier_id, :integer
         
     | 
| 
      
 163 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 164 
     | 
    
         
            +
                  #
         
     | 
| 
       149 
165 
     | 
    
         
             
                  # generates:
         
     | 
| 
       150 
     | 
    
         
            -
                  # 
     | 
| 
       151 
     | 
    
         
            -
                  # 
     | 
| 
       152 
     | 
    
         
            -
                  # 
     | 
| 
       153 
     | 
    
         
            -
                  # 
     | 
| 
      
 166 
     | 
    
         
            +
                  #
         
     | 
| 
      
 167 
     | 
    
         
            +
                  #   CREATE TABLE categories_suppliers (
         
     | 
| 
      
 168 
     | 
    
         
            +
                  #     category_id int,
         
     | 
| 
      
 169 
     | 
    
         
            +
                  #     supplier_id int
         
     | 
| 
      
 170 
     | 
    
         
            +
                  #   )
         
     | 
| 
       154 
171 
     | 
    
         
             
                  #
         
     | 
| 
       155 
172 
     | 
    
         
             
                  # See also TableDefinition#column for details on how to create columns.
         
     | 
| 
       156 
173 
     | 
    
         
             
                  def create_table(table_name, options = {})
         
     | 
| 
       157 
     | 
    
         
            -
                    td =  
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
      
 174 
     | 
    
         
            +
                    td = create_table_definition table_name, options[:temporary], options[:options]
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                    unless options[:id] == false
         
     | 
| 
      
 177 
     | 
    
         
            +
                      pk = options.fetch(:primary_key) {
         
     | 
| 
      
 178 
     | 
    
         
            +
                        Base.get_primary_key table_name.to_s.singularize
         
     | 
| 
      
 179 
     | 
    
         
            +
                      }
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
                      td.primary_key pk, options.fetch(:id, :primary_key), options
         
     | 
| 
      
 182 
     | 
    
         
            +
                    end
         
     | 
| 
       159 
183 
     | 
    
         | 
| 
       160 
184 
     | 
    
         
             
                    yield td if block_given?
         
     | 
| 
       161 
185 
     | 
    
         | 
| 
         @@ -163,95 +187,167 @@ module ActiveRecord 
     | 
|
| 
       163 
187 
     | 
    
         
             
                      drop_table(table_name, options)
         
     | 
| 
       164 
188 
     | 
    
         
             
                    end
         
     | 
| 
       165 
189 
     | 
    
         | 
| 
       166 
     | 
    
         
            -
                     
     | 
| 
       167 
     | 
    
         
            -
                     
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
       169 
     | 
    
         
            -
             
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
      
 190 
     | 
    
         
            +
                    execute schema_creation.accept td
         
     | 
| 
      
 191 
     | 
    
         
            +
                    td.indexes.each_pair { |c,o| add_index table_name, c, o }
         
     | 
| 
      
 192 
     | 
    
         
            +
                  end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                  # Creates a new join table with the name created using the lexical order of the first two
         
     | 
| 
      
 195 
     | 
    
         
            +
                  # arguments. These arguments can be a String or a Symbol.
         
     | 
| 
      
 196 
     | 
    
         
            +
                  #
         
     | 
| 
      
 197 
     | 
    
         
            +
                  #   # Creates a table called 'assemblies_parts' with no id.
         
     | 
| 
      
 198 
     | 
    
         
            +
                  #   create_join_table(:assemblies, :parts)
         
     | 
| 
      
 199 
     | 
    
         
            +
                  #
         
     | 
| 
      
 200 
     | 
    
         
            +
                  # You can pass a +options+ hash can include the following keys:
         
     | 
| 
      
 201 
     | 
    
         
            +
                  # [<tt>:table_name</tt>]
         
     | 
| 
      
 202 
     | 
    
         
            +
                  #   Sets the table name overriding the default
         
     | 
| 
      
 203 
     | 
    
         
            +
                  # [<tt>:column_options</tt>]
         
     | 
| 
      
 204 
     | 
    
         
            +
                  #   Any extra options you want appended to the columns definition.
         
     | 
| 
      
 205 
     | 
    
         
            +
                  # [<tt>:options</tt>]
         
     | 
| 
      
 206 
     | 
    
         
            +
                  #   Any extra options you want appended to the table definition.
         
     | 
| 
      
 207 
     | 
    
         
            +
                  # [<tt>:temporary</tt>]
         
     | 
| 
      
 208 
     | 
    
         
            +
                  #   Make a temporary table.
         
     | 
| 
      
 209 
     | 
    
         
            +
                  # [<tt>:force</tt>]
         
     | 
| 
      
 210 
     | 
    
         
            +
                  #   Set to true to drop the table before creating it.
         
     | 
| 
      
 211 
     | 
    
         
            +
                  #   Defaults to false.
         
     | 
| 
      
 212 
     | 
    
         
            +
                  #
         
     | 
| 
      
 213 
     | 
    
         
            +
                  # Note that +create_join_table+ does not create any indices by default; you can use
         
     | 
| 
      
 214 
     | 
    
         
            +
                  # its block form to do so yourself:
         
     | 
| 
      
 215 
     | 
    
         
            +
                  #
         
     | 
| 
      
 216 
     | 
    
         
            +
                  #   create_join_table :products, :categories do |t|
         
     | 
| 
      
 217 
     | 
    
         
            +
                  #     t.index :product_id
         
     | 
| 
      
 218 
     | 
    
         
            +
                  #     t.index :category_id
         
     | 
| 
      
 219 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 220 
     | 
    
         
            +
                  #
         
     | 
| 
      
 221 
     | 
    
         
            +
                  # ====== Add a backend specific option to the generated SQL (MySQL)
         
     | 
| 
      
 222 
     | 
    
         
            +
                  #
         
     | 
| 
      
 223 
     | 
    
         
            +
                  #   create_join_table(:assemblies, :parts, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8')
         
     | 
| 
      
 224 
     | 
    
         
            +
                  #
         
     | 
| 
      
 225 
     | 
    
         
            +
                  # generates:
         
     | 
| 
      
 226 
     | 
    
         
            +
                  #
         
     | 
| 
      
 227 
     | 
    
         
            +
                  #   CREATE TABLE assemblies_parts (
         
     | 
| 
      
 228 
     | 
    
         
            +
                  #     assembly_id int NOT NULL,
         
     | 
| 
      
 229 
     | 
    
         
            +
                  #     part_id int NOT NULL,
         
     | 
| 
      
 230 
     | 
    
         
            +
                  #   ) ENGINE=InnoDB DEFAULT CHARSET=utf8
         
     | 
| 
      
 231 
     | 
    
         
            +
                  #
         
     | 
| 
      
 232 
     | 
    
         
            +
                  def create_join_table(table_1, table_2, options = {})
         
     | 
| 
      
 233 
     | 
    
         
            +
                    join_table_name = find_join_table_name(table_1, table_2, options)
         
     | 
| 
      
 234 
     | 
    
         
            +
             
     | 
| 
      
 235 
     | 
    
         
            +
                    column_options = options.delete(:column_options) || {}
         
     | 
| 
      
 236 
     | 
    
         
            +
                    column_options.reverse_merge!(null: false)
         
     | 
| 
      
 237 
     | 
    
         
            +
             
     | 
| 
      
 238 
     | 
    
         
            +
                    t1_column, t2_column = [table_1, table_2].map{ |t| t.to_s.singularize.foreign_key }
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
                    create_table(join_table_name, options.merge!(id: false)) do |td|
         
     | 
| 
      
 241 
     | 
    
         
            +
                      td.integer t1_column, column_options
         
     | 
| 
      
 242 
     | 
    
         
            +
                      td.integer t2_column, column_options
         
     | 
| 
      
 243 
     | 
    
         
            +
                      yield td if block_given?
         
     | 
| 
      
 244 
     | 
    
         
            +
                    end
         
     | 
| 
      
 245 
     | 
    
         
            +
                  end
         
     | 
| 
      
 246 
     | 
    
         
            +
             
     | 
| 
      
 247 
     | 
    
         
            +
                  # Drops the join table specified by the given arguments.
         
     | 
| 
      
 248 
     | 
    
         
            +
                  # See +create_join_table+ for details.
         
     | 
| 
      
 249 
     | 
    
         
            +
                  #
         
     | 
| 
      
 250 
     | 
    
         
            +
                  # Although this command ignores the block if one is given, it can be helpful
         
     | 
| 
      
 251 
     | 
    
         
            +
                  # to provide one in a migration's +change+ method so it can be reverted.
         
     | 
| 
      
 252 
     | 
    
         
            +
                  # In that case, the block will be used by create_join_table.
         
     | 
| 
      
 253 
     | 
    
         
            +
                  def drop_join_table(table_1, table_2, options = {})
         
     | 
| 
      
 254 
     | 
    
         
            +
                    join_table_name = find_join_table_name(table_1, table_2, options)
         
     | 
| 
      
 255 
     | 
    
         
            +
                    drop_table(join_table_name)
         
     | 
| 
       171 
256 
     | 
    
         
             
                  end
         
     | 
| 
       172 
257 
     | 
    
         | 
| 
       173 
258 
     | 
    
         
             
                  # A block for changing columns in +table+.
         
     | 
| 
       174 
259 
     | 
    
         
             
                  #
         
     | 
| 
       175 
     | 
    
         
            -
                  #  
     | 
| 
       176 
     | 
    
         
            -
                  # 
     | 
| 
       177 
     | 
    
         
            -
                  # 
     | 
| 
       178 
     | 
    
         
            -
                  # 
     | 
| 
       179 
     | 
    
         
            -
                  # 
     | 
| 
       180 
     | 
    
         
            -
                  #  end
         
     | 
| 
      
 260 
     | 
    
         
            +
                  #   # change_table() yields a Table instance
         
     | 
| 
      
 261 
     | 
    
         
            +
                  #   change_table(:suppliers) do |t|
         
     | 
| 
      
 262 
     | 
    
         
            +
                  #     t.column :name, :string, limit: 60
         
     | 
| 
      
 263 
     | 
    
         
            +
                  #     # Other column alterations here
         
     | 
| 
      
 264 
     | 
    
         
            +
                  #   end
         
     | 
| 
       181 
265 
     | 
    
         
             
                  #
         
     | 
| 
       182 
266 
     | 
    
         
             
                  # The +options+ hash can include the following keys:
         
     | 
| 
       183 
267 
     | 
    
         
             
                  # [<tt>:bulk</tt>]
         
     | 
| 
       184 
268 
     | 
    
         
             
                  #   Set this to true to make this a bulk alter query, such as
         
     | 
| 
       185 
     | 
    
         
            -
                  # 
     | 
| 
      
 269 
     | 
    
         
            +
                  #
         
     | 
| 
      
 270 
     | 
    
         
            +
                  #     ALTER TABLE `users` ADD COLUMN age INT(11), ADD COLUMN birthdate DATETIME ...
         
     | 
| 
       186 
271 
     | 
    
         
             
                  #
         
     | 
| 
       187 
272 
     | 
    
         
             
                  #   Defaults to false.
         
     | 
| 
       188 
273 
     | 
    
         
             
                  #
         
     | 
| 
       189 
     | 
    
         
            -
                  # ===== Examples
         
     | 
| 
       190 
274 
     | 
    
         
             
                  # ====== Add a column
         
     | 
| 
       191 
     | 
    
         
            -
                  # 
     | 
| 
       192 
     | 
    
         
            -
                  # 
     | 
| 
       193 
     | 
    
         
            -
                  # 
     | 
| 
      
 275 
     | 
    
         
            +
                  #
         
     | 
| 
      
 276 
     | 
    
         
            +
                  #   change_table(:suppliers) do |t|
         
     | 
| 
      
 277 
     | 
    
         
            +
                  #     t.column :name, :string, limit: 60
         
     | 
| 
      
 278 
     | 
    
         
            +
                  #   end
         
     | 
| 
       194 
279 
     | 
    
         
             
                  #
         
     | 
| 
       195 
280 
     | 
    
         
             
                  # ====== Add 2 integer columns
         
     | 
| 
       196 
     | 
    
         
            -
                  # 
     | 
| 
       197 
     | 
    
         
            -
                  # 
     | 
| 
       198 
     | 
    
         
            -
                  # 
     | 
| 
      
 281 
     | 
    
         
            +
                  #
         
     | 
| 
      
 282 
     | 
    
         
            +
                  #   change_table(:suppliers) do |t|
         
     | 
| 
      
 283 
     | 
    
         
            +
                  #     t.integer :width, :height, null: false, default: 0
         
     | 
| 
      
 284 
     | 
    
         
            +
                  #   end
         
     | 
| 
       199 
285 
     | 
    
         
             
                  #
         
     | 
| 
       200 
286 
     | 
    
         
             
                  # ====== Add created_at/updated_at columns
         
     | 
| 
       201 
     | 
    
         
            -
                  # 
     | 
| 
       202 
     | 
    
         
            -
                  # 
     | 
| 
       203 
     | 
    
         
            -
                  # 
     | 
| 
      
 287 
     | 
    
         
            +
                  #
         
     | 
| 
      
 288 
     | 
    
         
            +
                  #   change_table(:suppliers) do |t|
         
     | 
| 
      
 289 
     | 
    
         
            +
                  #     t.timestamps
         
     | 
| 
      
 290 
     | 
    
         
            +
                  #   end
         
     | 
| 
       204 
291 
     | 
    
         
             
                  #
         
     | 
| 
       205 
292 
     | 
    
         
             
                  # ====== Add a foreign key column
         
     | 
| 
       206 
     | 
    
         
            -
                  #  change_table(:suppliers) do |t|
         
     | 
| 
       207 
     | 
    
         
            -
                  #    t.references :company
         
     | 
| 
       208 
     | 
    
         
            -
                  #  end
         
     | 
| 
       209 
293 
     | 
    
         
             
                  #
         
     | 
| 
       210 
     | 
    
         
            -
                  # 
     | 
| 
      
 294 
     | 
    
         
            +
                  #   change_table(:suppliers) do |t|
         
     | 
| 
      
 295 
     | 
    
         
            +
                  #     t.references :company
         
     | 
| 
      
 296 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 297 
     | 
    
         
            +
                  #
         
     | 
| 
      
 298 
     | 
    
         
            +
                  # Creates a <tt>company_id(integer)</tt> column.
         
     | 
| 
       211 
299 
     | 
    
         
             
                  #
         
     | 
| 
       212 
300 
     | 
    
         
             
                  # ====== Add a polymorphic foreign key column
         
     | 
| 
      
 301 
     | 
    
         
            +
                  #
         
     | 
| 
       213 
302 
     | 
    
         
             
                  #  change_table(:suppliers) do |t|
         
     | 
| 
       214 
     | 
    
         
            -
                  #    t.belongs_to :company, : 
     | 
| 
      
 303 
     | 
    
         
            +
                  #    t.belongs_to :company, polymorphic: true
         
     | 
| 
       215 
304 
     | 
    
         
             
                  #  end
         
     | 
| 
       216 
305 
     | 
    
         
             
                  #
         
     | 
| 
       217 
     | 
    
         
            -
                  # Creates <tt>company_type(varchar)</tt> and <tt>company_id(integer)</tt> columns
         
     | 
| 
      
 306 
     | 
    
         
            +
                  # Creates <tt>company_type(varchar)</tt> and <tt>company_id(integer)</tt> columns.
         
     | 
| 
       218 
307 
     | 
    
         
             
                  #
         
     | 
| 
       219 
308 
     | 
    
         
             
                  # ====== Remove a column
         
     | 
| 
      
 309 
     | 
    
         
            +
                  #
         
     | 
| 
       220 
310 
     | 
    
         
             
                  #  change_table(:suppliers) do |t|
         
     | 
| 
       221 
311 
     | 
    
         
             
                  #    t.remove :company
         
     | 
| 
       222 
312 
     | 
    
         
             
                  #  end
         
     | 
| 
       223 
313 
     | 
    
         
             
                  #
         
     | 
| 
       224 
314 
     | 
    
         
             
                  # ====== Remove several columns
         
     | 
| 
      
 315 
     | 
    
         
            +
                  #
         
     | 
| 
       225 
316 
     | 
    
         
             
                  #  change_table(:suppliers) do |t|
         
     | 
| 
       226 
317 
     | 
    
         
             
                  #    t.remove :company_id
         
     | 
| 
       227 
318 
     | 
    
         
             
                  #    t.remove :width, :height
         
     | 
| 
       228 
319 
     | 
    
         
             
                  #  end
         
     | 
| 
       229 
320 
     | 
    
         
             
                  #
         
     | 
| 
       230 
321 
     | 
    
         
             
                  # ====== Remove an index
         
     | 
| 
      
 322 
     | 
    
         
            +
                  #
         
     | 
| 
       231 
323 
     | 
    
         
             
                  #  change_table(:suppliers) do |t|
         
     | 
| 
       232 
324 
     | 
    
         
             
                  #    t.remove_index :company_id
         
     | 
| 
       233 
325 
     | 
    
         
             
                  #  end
         
     | 
| 
       234 
326 
     | 
    
         
             
                  #
         
     | 
| 
       235 
     | 
    
         
            -
                  # See also Table for details on
         
     | 
| 
       236 
     | 
    
         
            -
                  # all of the various column transformation
         
     | 
| 
      
 327 
     | 
    
         
            +
                  # See also Table for details on all of the various column transformation.
         
     | 
| 
       237 
328 
     | 
    
         
             
                  def change_table(table_name, options = {})
         
     | 
| 
       238 
329 
     | 
    
         
             
                    if supports_bulk_alter? && options[:bulk]
         
     | 
| 
       239 
330 
     | 
    
         
             
                      recorder = ActiveRecord::Migration::CommandRecorder.new(self)
         
     | 
| 
       240 
     | 
    
         
            -
                      yield  
     | 
| 
      
 331 
     | 
    
         
            +
                      yield update_table_definition(table_name, recorder)
         
     | 
| 
       241 
332 
     | 
    
         
             
                      bulk_change_table(table_name, recorder.commands)
         
     | 
| 
       242 
333 
     | 
    
         
             
                    else
         
     | 
| 
       243 
     | 
    
         
            -
                      yield  
     | 
| 
      
 334 
     | 
    
         
            +
                      yield update_table_definition(table_name, self)
         
     | 
| 
       244 
335 
     | 
    
         
             
                    end
         
     | 
| 
       245 
336 
     | 
    
         
             
                  end
         
     | 
| 
       246 
337 
     | 
    
         | 
| 
       247 
338 
     | 
    
         
             
                  # Renames a table.
         
     | 
| 
       248 
     | 
    
         
            -
                  # 
     | 
| 
       249 
     | 
    
         
            -
                  # 
     | 
| 
      
 339 
     | 
    
         
            +
                  #
         
     | 
| 
      
 340 
     | 
    
         
            +
                  #   rename_table('octopuses', 'octopi')
         
     | 
| 
      
 341 
     | 
    
         
            +
                  #
         
     | 
| 
       250 
342 
     | 
    
         
             
                  def rename_table(table_name, new_name)
         
     | 
| 
       251 
343 
     | 
    
         
             
                    raise NotImplementedError, "rename_table is not implemented"
         
     | 
| 
       252 
344 
     | 
    
         
             
                  end
         
     | 
| 
       253 
345 
     | 
    
         | 
| 
       254 
346 
     | 
    
         
             
                  # Drops a table from the database.
         
     | 
| 
      
 347 
     | 
    
         
            +
                  #
         
     | 
| 
      
 348 
     | 
    
         
            +
                  # Although this command ignores +options+ and the block if one is given, it can be helpful
         
     | 
| 
      
 349 
     | 
    
         
            +
                  # to provide these in a migration's +change+ method so it can be reverted.
         
     | 
| 
      
 350 
     | 
    
         
            +
                  # In that case, +options+ and the block will be used by create_table.
         
     | 
| 
       255 
351 
     | 
    
         
             
                  def drop_table(table_name, options = {})
         
     | 
| 
       256 
352 
     | 
    
         
             
                    execute "DROP TABLE #{quote_table_name(table_name)}"
         
     | 
| 
       257 
353 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -259,49 +355,80 @@ module ActiveRecord 
     | 
|
| 
       259 
355 
     | 
    
         
             
                  # Adds a new column to the named table.
         
     | 
| 
       260 
356 
     | 
    
         
             
                  # See TableDefinition#column for details of the options you can use.
         
     | 
| 
       261 
357 
     | 
    
         
             
                  def add_column(table_name, column_name, type, options = {})
         
     | 
| 
       262 
     | 
    
         
            -
                     
     | 
| 
       263 
     | 
    
         
            -
                     
     | 
| 
       264 
     | 
    
         
            -
                    execute 
     | 
| 
       265 
     | 
    
         
            -
                  end
         
     | 
| 
       266 
     | 
    
         
            -
             
     | 
| 
       267 
     | 
    
         
            -
                  # Removes the column(s) from the table definition.
         
     | 
| 
       268 
     | 
    
         
            -
                  # ===== Examples
         
     | 
| 
       269 
     | 
    
         
            -
                  #  remove_column(:suppliers, :qualification)
         
     | 
| 
       270 
     | 
    
         
            -
                  #  remove_columns(:suppliers, :qualification, :experience)
         
     | 
| 
       271 
     | 
    
         
            -
                  def remove_column(table_name, *column_names)
         
     | 
| 
       272 
     | 
    
         
            -
                    if column_names.flatten!
         
     | 
| 
       273 
     | 
    
         
            -
                      message = 'Passing array to remove_columns is deprecated, please use ' +
         
     | 
| 
       274 
     | 
    
         
            -
                                'multiple arguments, like: `remove_columns(:posts, :foo, :bar)`'
         
     | 
| 
       275 
     | 
    
         
            -
                      ActiveSupport::Deprecation.warn message, caller
         
     | 
| 
       276 
     | 
    
         
            -
                    end
         
     | 
| 
      
 358 
     | 
    
         
            +
                    at = create_alter_table table_name
         
     | 
| 
      
 359 
     | 
    
         
            +
                    at.add_column(column_name, type, options)
         
     | 
| 
      
 360 
     | 
    
         
            +
                    execute schema_creation.accept at
         
     | 
| 
      
 361 
     | 
    
         
            +
                  end
         
     | 
| 
       277 
362 
     | 
    
         | 
| 
       278 
     | 
    
         
            -
             
     | 
| 
       279 
     | 
    
         
            -
             
     | 
| 
      
 363 
     | 
    
         
            +
                  # Removes the given columns from the table definition.
         
     | 
| 
      
 364 
     | 
    
         
            +
                  #
         
     | 
| 
      
 365 
     | 
    
         
            +
                  #   remove_columns(:suppliers, :qualification, :experience)
         
     | 
| 
      
 366 
     | 
    
         
            +
                  #
         
     | 
| 
      
 367 
     | 
    
         
            +
                  def remove_columns(table_name, *column_names)
         
     | 
| 
      
 368 
     | 
    
         
            +
                    raise ArgumentError.new("You must specify at least one column name. Example: remove_columns(:people, :first_name)") if column_names.empty?
         
     | 
| 
      
 369 
     | 
    
         
            +
                    column_names.each do |column_name|
         
     | 
| 
      
 370 
     | 
    
         
            +
                      remove_column(table_name, column_name)
         
     | 
| 
       280 
371 
     | 
    
         
             
                    end
         
     | 
| 
       281 
372 
     | 
    
         
             
                  end
         
     | 
| 
       282 
     | 
    
         
            -
             
     | 
| 
      
 373 
     | 
    
         
            +
             
     | 
| 
      
 374 
     | 
    
         
            +
                  # Removes the column from the table definition.
         
     | 
| 
      
 375 
     | 
    
         
            +
                  #
         
     | 
| 
      
 376 
     | 
    
         
            +
                  #   remove_column(:suppliers, :qualification)
         
     | 
| 
      
 377 
     | 
    
         
            +
                  #
         
     | 
| 
      
 378 
     | 
    
         
            +
                  # The +type+ and +options+ parameters will be ignored if present. It can be helpful
         
     | 
| 
      
 379 
     | 
    
         
            +
                  # to provide these in a migration's +change+ method so it can be reverted.
         
     | 
| 
      
 380 
     | 
    
         
            +
                  # In that case, +type+ and +options+ will be used by add_column.
         
     | 
| 
      
 381 
     | 
    
         
            +
                  def remove_column(table_name, column_name, type = nil, options = {})
         
     | 
| 
      
 382 
     | 
    
         
            +
                    execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{quote_column_name(column_name)}"
         
     | 
| 
      
 383 
     | 
    
         
            +
                  end
         
     | 
| 
       283 
384 
     | 
    
         | 
| 
       284 
385 
     | 
    
         
             
                  # Changes the column's definition according to the new options.
         
     | 
| 
       285 
386 
     | 
    
         
             
                  # See TableDefinition#column for details of the options you can use.
         
     | 
| 
       286 
     | 
    
         
            -
                  # 
     | 
| 
       287 
     | 
    
         
            -
                  # 
     | 
| 
       288 
     | 
    
         
            -
                  # 
     | 
| 
      
 387 
     | 
    
         
            +
                  #
         
     | 
| 
      
 388 
     | 
    
         
            +
                  #   change_column(:suppliers, :name, :string, limit: 80)
         
     | 
| 
      
 389 
     | 
    
         
            +
                  #   change_column(:accounts, :description, :text)
         
     | 
| 
      
 390 
     | 
    
         
            +
                  #
         
     | 
| 
       289 
391 
     | 
    
         
             
                  def change_column(table_name, column_name, type, options = {})
         
     | 
| 
       290 
392 
     | 
    
         
             
                    raise NotImplementedError, "change_column is not implemented"
         
     | 
| 
       291 
393 
     | 
    
         
             
                  end
         
     | 
| 
       292 
394 
     | 
    
         | 
| 
       293 
     | 
    
         
            -
                  # Sets a new default value for a column 
     | 
| 
       294 
     | 
    
         
            -
                  # 
     | 
| 
       295 
     | 
    
         
            -
                  # 
     | 
| 
       296 
     | 
    
         
            -
                  # 
     | 
| 
       297 
     | 
    
         
            -
                  # 
     | 
| 
      
 395 
     | 
    
         
            +
                  # Sets a new default value for a column:
         
     | 
| 
      
 396 
     | 
    
         
            +
                  #
         
     | 
| 
      
 397 
     | 
    
         
            +
                  #   change_column_default(:suppliers, :qualification, 'new')
         
     | 
| 
      
 398 
     | 
    
         
            +
                  #   change_column_default(:accounts, :authorized, 1)
         
     | 
| 
      
 399 
     | 
    
         
            +
                  #
         
     | 
| 
      
 400 
     | 
    
         
            +
                  # Setting the default to +nil+ effectively drops the default:
         
     | 
| 
      
 401 
     | 
    
         
            +
                  #
         
     | 
| 
      
 402 
     | 
    
         
            +
                  #   change_column_default(:users, :email, nil)
         
     | 
| 
      
 403 
     | 
    
         
            +
                  #
         
     | 
| 
       298 
404 
     | 
    
         
             
                  def change_column_default(table_name, column_name, default)
         
     | 
| 
       299 
405 
     | 
    
         
             
                    raise NotImplementedError, "change_column_default is not implemented"
         
     | 
| 
       300 
406 
     | 
    
         
             
                  end
         
     | 
| 
       301 
407 
     | 
    
         | 
| 
      
 408 
     | 
    
         
            +
                  # Sets or removes a +NOT NULL+ constraint on a column. The +null+ flag
         
     | 
| 
      
 409 
     | 
    
         
            +
                  # indicates whether the value can be +NULL+. For example
         
     | 
| 
      
 410 
     | 
    
         
            +
                  #
         
     | 
| 
      
 411 
     | 
    
         
            +
                  #   change_column_null(:users, :nickname, false)
         
     | 
| 
      
 412 
     | 
    
         
            +
                  #
         
     | 
| 
      
 413 
     | 
    
         
            +
                  # says nicknames cannot be +NULL+ (adds the constraint), whereas
         
     | 
| 
      
 414 
     | 
    
         
            +
                  #
         
     | 
| 
      
 415 
     | 
    
         
            +
                  #   change_column_null(:users, :nickname, true)
         
     | 
| 
      
 416 
     | 
    
         
            +
                  #
         
     | 
| 
      
 417 
     | 
    
         
            +
                  # allows them to be +NULL+ (drops the constraint).
         
     | 
| 
      
 418 
     | 
    
         
            +
                  #
         
     | 
| 
      
 419 
     | 
    
         
            +
                  # The method accepts an optional fourth argument to replace existing
         
     | 
| 
      
 420 
     | 
    
         
            +
                  # +NULL+s with some other value. Use that one when enabling the
         
     | 
| 
      
 421 
     | 
    
         
            +
                  # constraint if needed, since otherwise those rows would not be valid.
         
     | 
| 
      
 422 
     | 
    
         
            +
                  #
         
     | 
| 
      
 423 
     | 
    
         
            +
                  # Please note the fourth argument does not set a column's default.
         
     | 
| 
      
 424 
     | 
    
         
            +
                  def change_column_null(table_name, column_name, null, default = nil)
         
     | 
| 
      
 425 
     | 
    
         
            +
                    raise NotImplementedError, "change_column_null is not implemented"
         
     | 
| 
      
 426 
     | 
    
         
            +
                  end
         
     | 
| 
      
 427 
     | 
    
         
            +
             
     | 
| 
       302 
428 
     | 
    
         
             
                  # Renames a column.
         
     | 
| 
       303 
     | 
    
         
            -
                  # 
     | 
| 
       304 
     | 
    
         
            -
                  # 
     | 
| 
      
 429 
     | 
    
         
            +
                  #
         
     | 
| 
      
 430 
     | 
    
         
            +
                  #   rename_column(:suppliers, :description, :name)
         
     | 
| 
      
 431 
     | 
    
         
            +
                  #
         
     | 
| 
       305 
432 
     | 
    
         
             
                  def rename_column(table_name, column_name, new_column_name)
         
     | 
| 
       306 
433 
     | 
    
         
             
                    raise NotImplementedError, "rename_column is not implemented"
         
     | 
| 
       307 
434 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -312,56 +439,107 @@ module ActiveRecord 
     | 
|
| 
       312 
439 
     | 
    
         
             
                  # The index will be named after the table and the column name(s), unless
         
     | 
| 
       313 
440 
     | 
    
         
             
                  # you pass <tt>:name</tt> as an option.
         
     | 
| 
       314 
441 
     | 
    
         
             
                  #
         
     | 
| 
       315 
     | 
    
         
            -
                  # ===== Examples
         
     | 
| 
       316 
     | 
    
         
            -
                  #
         
     | 
| 
       317 
442 
     | 
    
         
             
                  # ====== Creating a simple index
         
     | 
| 
       318 
     | 
    
         
            -
                  # 
     | 
| 
       319 
     | 
    
         
            -
                  #  
     | 
| 
       320 
     | 
    
         
            -
                  # 
     | 
| 
      
 443 
     | 
    
         
            +
                  #
         
     | 
| 
      
 444 
     | 
    
         
            +
                  #   add_index(:suppliers, :name)
         
     | 
| 
      
 445 
     | 
    
         
            +
                  #
         
     | 
| 
      
 446 
     | 
    
         
            +
                  # generates:
         
     | 
| 
      
 447 
     | 
    
         
            +
                  #
         
     | 
| 
      
 448 
     | 
    
         
            +
                  #   CREATE INDEX suppliers_name_index ON suppliers(name)
         
     | 
| 
       321 
449 
     | 
    
         
             
                  #
         
     | 
| 
       322 
450 
     | 
    
         
             
                  # ====== Creating a unique index
         
     | 
| 
       323 
     | 
    
         
            -
                  # 
     | 
| 
       324 
     | 
    
         
            -
                  #  
     | 
| 
       325 
     | 
    
         
            -
                  # 
     | 
| 
      
 451 
     | 
    
         
            +
                  #
         
     | 
| 
      
 452 
     | 
    
         
            +
                  #   add_index(:accounts, [:branch_id, :party_id], unique: true)
         
     | 
| 
      
 453 
     | 
    
         
            +
                  #
         
     | 
| 
      
 454 
     | 
    
         
            +
                  # generates:
         
     | 
| 
      
 455 
     | 
    
         
            +
                  #
         
     | 
| 
      
 456 
     | 
    
         
            +
                  #   CREATE UNIQUE INDEX accounts_branch_id_party_id_index ON accounts(branch_id, party_id)
         
     | 
| 
       326 
457 
     | 
    
         
             
                  #
         
     | 
| 
       327 
458 
     | 
    
         
             
                  # ====== Creating a named index
         
     | 
| 
       328 
     | 
    
         
            -
                  # 
     | 
| 
       329 
     | 
    
         
            -
                  #  
     | 
| 
      
 459 
     | 
    
         
            +
                  #
         
     | 
| 
      
 460 
     | 
    
         
            +
                  #   add_index(:accounts, [:branch_id, :party_id], unique: true, name: 'by_branch_party')
         
     | 
| 
      
 461 
     | 
    
         
            +
                  #
         
     | 
| 
      
 462 
     | 
    
         
            +
                  # generates:
         
     | 
| 
      
 463 
     | 
    
         
            +
                  #
         
     | 
| 
       330 
464 
     | 
    
         
             
                  #  CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id)
         
     | 
| 
       331 
465 
     | 
    
         
             
                  #
         
     | 
| 
       332 
466 
     | 
    
         
             
                  # ====== Creating an index with specific key length
         
     | 
| 
       333 
     | 
    
         
            -
                  #  add_index(:accounts, :name, :name => 'by_name', :length => 10)
         
     | 
| 
       334 
     | 
    
         
            -
                  # generates
         
     | 
| 
       335 
     | 
    
         
            -
                  #  CREATE INDEX by_name ON accounts(name(10))
         
     | 
| 
       336 
467 
     | 
    
         
             
                  #
         
     | 
| 
       337 
     | 
    
         
            -
                  # 
     | 
| 
       338 
     | 
    
         
            -
                  # 
     | 
| 
       339 
     | 
    
         
            -
                  # 
     | 
| 
      
 468 
     | 
    
         
            +
                  #   add_index(:accounts, :name, name: 'by_name', length: 10)
         
     | 
| 
      
 469 
     | 
    
         
            +
                  #
         
     | 
| 
      
 470 
     | 
    
         
            +
                  # generates:
         
     | 
| 
      
 471 
     | 
    
         
            +
                  #
         
     | 
| 
      
 472 
     | 
    
         
            +
                  #   CREATE INDEX by_name ON accounts(name(10))
         
     | 
| 
      
 473 
     | 
    
         
            +
                  #
         
     | 
| 
      
 474 
     | 
    
         
            +
                  #   add_index(:accounts, [:name, :surname], name: 'by_name_surname', length: {name: 10, surname: 15})
         
     | 
| 
      
 475 
     | 
    
         
            +
                  #
         
     | 
| 
      
 476 
     | 
    
         
            +
                  # generates:
         
     | 
| 
      
 477 
     | 
    
         
            +
                  #
         
     | 
| 
      
 478 
     | 
    
         
            +
                  #   CREATE INDEX by_name_surname ON accounts(name(10), surname(15))
         
     | 
| 
       340 
479 
     | 
    
         
             
                  #
         
     | 
| 
       341 
     | 
    
         
            -
                  # Note: SQLite doesn't support index length
         
     | 
| 
      
 480 
     | 
    
         
            +
                  # Note: SQLite doesn't support index length.
         
     | 
| 
       342 
481 
     | 
    
         
             
                  #
         
     | 
| 
       343 
482 
     | 
    
         
             
                  # ====== Creating an index with a sort order (desc or asc, asc is the default)
         
     | 
| 
       344 
     | 
    
         
            -
                  #  add_index(:accounts, [:branch_id, :party_id, :surname], :order => {:branch_id => :desc, :part_id => :asc})
         
     | 
| 
       345 
     | 
    
         
            -
                  # generates
         
     | 
| 
       346 
     | 
    
         
            -
                  #  CREATE INDEX by_branch_desc_party ON accounts(branch_id DESC, party_id ASC, surname)
         
     | 
| 
       347 
483 
     | 
    
         
             
                  #
         
     | 
| 
       348 
     | 
    
         
            -
                  #  
     | 
| 
      
 484 
     | 
    
         
            +
                  #   add_index(:accounts, [:branch_id, :party_id, :surname], order: {branch_id: :desc, party_id: :asc})
         
     | 
| 
      
 485 
     | 
    
         
            +
                  #
         
     | 
| 
      
 486 
     | 
    
         
            +
                  # generates:
         
     | 
| 
      
 487 
     | 
    
         
            +
                  #
         
     | 
| 
      
 488 
     | 
    
         
            +
                  #   CREATE INDEX by_branch_desc_party ON accounts(branch_id DESC, party_id ASC, surname)
         
     | 
| 
      
 489 
     | 
    
         
            +
                  #
         
     | 
| 
      
 490 
     | 
    
         
            +
                  # Note: MySQL doesn't yet support index order (it accepts the syntax but ignores it).
         
     | 
| 
      
 491 
     | 
    
         
            +
                  #
         
     | 
| 
      
 492 
     | 
    
         
            +
                  # ====== Creating a partial index
         
     | 
| 
      
 493 
     | 
    
         
            +
                  #
         
     | 
| 
      
 494 
     | 
    
         
            +
                  #   add_index(:accounts, [:branch_id, :party_id], unique: true, where: "active")
         
     | 
| 
      
 495 
     | 
    
         
            +
                  #
         
     | 
| 
      
 496 
     | 
    
         
            +
                  # generates:
         
     | 
| 
      
 497 
     | 
    
         
            +
                  #
         
     | 
| 
      
 498 
     | 
    
         
            +
                  #   CREATE UNIQUE INDEX index_accounts_on_branch_id_and_party_id ON accounts(branch_id, party_id) WHERE active
         
     | 
| 
      
 499 
     | 
    
         
            +
                  #
         
     | 
| 
      
 500 
     | 
    
         
            +
                  # ====== Creating an index with a specific method
         
     | 
| 
      
 501 
     | 
    
         
            +
                  #
         
     | 
| 
      
 502 
     | 
    
         
            +
                  #   add_index(:developers, :name, using: 'btree')
         
     | 
| 
      
 503 
     | 
    
         
            +
                  #
         
     | 
| 
      
 504 
     | 
    
         
            +
                  # generates:
         
     | 
| 
      
 505 
     | 
    
         
            +
                  #
         
     | 
| 
      
 506 
     | 
    
         
            +
                  #   CREATE INDEX index_developers_on_name ON developers USING btree (name) -- PostgreSQL
         
     | 
| 
      
 507 
     | 
    
         
            +
                  #   CREATE INDEX index_developers_on_name USING btree ON developers (name) -- MySQL
         
     | 
| 
      
 508 
     | 
    
         
            +
                  #
         
     | 
| 
      
 509 
     | 
    
         
            +
                  # Note: only supported by PostgreSQL and MySQL
         
     | 
| 
      
 510 
     | 
    
         
            +
                  #
         
     | 
| 
      
 511 
     | 
    
         
            +
                  # ====== Creating an index with a specific type
         
     | 
| 
      
 512 
     | 
    
         
            +
                  #
         
     | 
| 
      
 513 
     | 
    
         
            +
                  #   add_index(:developers, :name, type: :fulltext)
         
     | 
| 
      
 514 
     | 
    
         
            +
                  #
         
     | 
| 
      
 515 
     | 
    
         
            +
                  # generates:
         
     | 
| 
      
 516 
     | 
    
         
            +
                  #
         
     | 
| 
      
 517 
     | 
    
         
            +
                  #   CREATE FULLTEXT INDEX index_developers_on_name ON developers (name) -- MySQL
         
     | 
| 
       349 
518 
     | 
    
         
             
                  #
         
     | 
| 
      
 519 
     | 
    
         
            +
                  # Note: only supported by MySQL. Supported: <tt>:fulltext</tt> and <tt>:spatial</tt> on MyISAM tables.
         
     | 
| 
       350 
520 
     | 
    
         
             
                  def add_index(table_name, column_name, options = {})
         
     | 
| 
       351 
     | 
    
         
            -
                    index_name, index_type, index_columns = add_index_options(table_name, column_name, options)
         
     | 
| 
       352 
     | 
    
         
            -
                    execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{index_columns})"
         
     | 
| 
      
 521 
     | 
    
         
            +
                    index_name, index_type, index_columns, index_options = add_index_options(table_name, column_name, options)
         
     | 
| 
      
 522 
     | 
    
         
            +
                    execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{index_columns})#{index_options}"
         
     | 
| 
       353 
523 
     | 
    
         
             
                  end
         
     | 
| 
       354 
524 
     | 
    
         | 
| 
       355 
     | 
    
         
            -
                  #  
     | 
| 
      
 525 
     | 
    
         
            +
                  # Removes the given index from the table.
         
     | 
| 
      
 526 
     | 
    
         
            +
                  #
         
     | 
| 
      
 527 
     | 
    
         
            +
                  # Removes the +index_accounts_on_column+ in the +accounts+ table.
         
     | 
| 
       356 
528 
     | 
    
         
             
                  #
         
     | 
| 
       357 
     | 
    
         
            -
                  # Remove the index_accounts_on_column in the accounts table.
         
     | 
| 
       358 
529 
     | 
    
         
             
                  #   remove_index :accounts, :column
         
     | 
| 
       359 
     | 
    
         
            -
                  # 
     | 
| 
       360 
     | 
    
         
            -
                  # 
     | 
| 
       361 
     | 
    
         
            -
                  # 
     | 
| 
       362 
     | 
    
         
            -
                  #   remove_index :accounts, : 
     | 
| 
       363 
     | 
    
         
            -
                  # 
     | 
| 
       364 
     | 
    
         
            -
                  # 
     | 
| 
      
 530 
     | 
    
         
            +
                  #
         
     | 
| 
      
 531 
     | 
    
         
            +
                  # Removes the index named +index_accounts_on_branch_id+ in the +accounts+ table.
         
     | 
| 
      
 532 
     | 
    
         
            +
                  #
         
     | 
| 
      
 533 
     | 
    
         
            +
                  #   remove_index :accounts, column: :branch_id
         
     | 
| 
      
 534 
     | 
    
         
            +
                  #
         
     | 
| 
      
 535 
     | 
    
         
            +
                  # Removes the index named +index_accounts_on_branch_id_and_party_id+ in the +accounts+ table.
         
     | 
| 
      
 536 
     | 
    
         
            +
                  #
         
     | 
| 
      
 537 
     | 
    
         
            +
                  #   remove_index :accounts, column: [:branch_id, :party_id]
         
     | 
| 
      
 538 
     | 
    
         
            +
                  #
         
     | 
| 
      
 539 
     | 
    
         
            +
                  # Removes the index named +by_branch_party+ in the +accounts+ table.
         
     | 
| 
      
 540 
     | 
    
         
            +
                  #
         
     | 
| 
      
 541 
     | 
    
         
            +
                  #   remove_index :accounts, name: :by_branch_party
         
     | 
| 
      
 542 
     | 
    
         
            +
                  #
         
     | 
| 
       365 
543 
     | 
    
         
             
                  def remove_index(table_name, options = {})
         
     | 
| 
       366 
544 
     | 
    
         
             
                    remove_index!(table_name, index_name_for_remove(table_name, options))
         
     | 
| 
       367 
545 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -370,10 +548,12 @@ module ActiveRecord 
     | 
|
| 
       370 
548 
     | 
    
         
             
                    execute "DROP INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}"
         
     | 
| 
       371 
549 
     | 
    
         
             
                  end
         
     | 
| 
       372 
550 
     | 
    
         | 
| 
       373 
     | 
    
         
            -
                  #  
     | 
| 
      
 551 
     | 
    
         
            +
                  # Renames an index.
         
     | 
| 
      
 552 
     | 
    
         
            +
                  #
         
     | 
| 
      
 553 
     | 
    
         
            +
                  # Rename the +index_people_on_last_name+ index to +index_users_on_last_name+:
         
     | 
| 
       374 
554 
     | 
    
         
             
                  #
         
     | 
| 
       375 
     | 
    
         
            -
                  # Rename the index_people_on_last_name index to index_users_on_last_name
         
     | 
| 
       376 
555 
     | 
    
         
             
                  #   rename_index :people, 'index_people_on_last_name', 'index_users_on_last_name'
         
     | 
| 
      
 556 
     | 
    
         
            +
                  #
         
     | 
| 
       377 
557 
     | 
    
         
             
                  def rename_index(table_name, old_name, new_name)
         
     | 
| 
       378 
558 
     | 
    
         
             
                    # this is a naive implementation; some DBs may support this more efficiently (Postgres, for instance)
         
     | 
| 
       379 
559 
     | 
    
         
             
                    old_index_def = indexes(table_name).detect { |i| i.name == old_name }
         
     | 
| 
         @@ -383,9 +563,9 @@ module ActiveRecord 
     | 
|
| 
       383 
563 
     | 
    
         
             
                  end
         
     | 
| 
       384 
564 
     | 
    
         | 
| 
       385 
565 
     | 
    
         
             
                  def index_name(table_name, options) #:nodoc:
         
     | 
| 
       386 
     | 
    
         
            -
                    if Hash === options 
     | 
| 
      
 566 
     | 
    
         
            +
                    if Hash === options
         
     | 
| 
       387 
567 
     | 
    
         
             
                      if options[:column]
         
     | 
| 
       388 
     | 
    
         
            -
                        "index_#{table_name}_on_#{Array 
     | 
| 
      
 568 
     | 
    
         
            +
                        "index_#{table_name}_on_#{Array(options[:column]) * '_and_'}"
         
     | 
| 
       389 
569 
     | 
    
         
             
                      elsif options[:name]
         
     | 
| 
       390 
570 
     | 
    
         
             
                        options[:name]
         
     | 
| 
       391 
571 
     | 
    
         
             
                      else
         
     | 
| 
         @@ -396,7 +576,7 @@ module ActiveRecord 
     | 
|
| 
       396 
576 
     | 
    
         
             
                    end
         
     | 
| 
       397 
577 
     | 
    
         
             
                  end
         
     | 
| 
       398 
578 
     | 
    
         | 
| 
       399 
     | 
    
         
            -
                  #  
     | 
| 
      
 579 
     | 
    
         
            +
                  # Verifies the existence of an index with a given name.
         
     | 
| 
       400 
580 
     | 
    
         
             
                  #
         
     | 
| 
       401 
581 
     | 
    
         
             
                  # The default argument is returned if the underlying implementation does not define the indexes method,
         
     | 
| 
       402 
582 
     | 
    
         
             
                  # as there's no way to determine the correct answer in that case.
         
     | 
| 
         @@ -406,45 +586,63 @@ module ActiveRecord 
     | 
|
| 
       406 
586 
     | 
    
         
             
                    indexes(table_name).detect { |i| i.name == index_name }
         
     | 
| 
       407 
587 
     | 
    
         
             
                  end
         
     | 
| 
       408 
588 
     | 
    
         | 
| 
       409 
     | 
    
         
            -
                  #  
     | 
| 
       410 
     | 
    
         
            -
                  #  
     | 
| 
       411 
     | 
    
         
            -
                   
     | 
| 
      
 589 
     | 
    
         
            +
                  # Adds a reference. Optionally adds a +type+ column, if <tt>:polymorphic</tt> option is provided.
         
     | 
| 
      
 590 
     | 
    
         
            +
                  # <tt>add_reference</tt> and <tt>add_belongs_to</tt> are acceptable.
         
     | 
| 
      
 591 
     | 
    
         
            +
                  #
         
     | 
| 
      
 592 
     | 
    
         
            +
                  # ====== Create a user_id column
         
     | 
| 
      
 593 
     | 
    
         
            +
                  #
         
     | 
| 
      
 594 
     | 
    
         
            +
                  #   add_reference(:products, :user)
         
     | 
| 
      
 595 
     | 
    
         
            +
                  #
         
     | 
| 
      
 596 
     | 
    
         
            +
                  # ====== Create a supplier_id and supplier_type columns
         
     | 
| 
      
 597 
     | 
    
         
            +
                  #
         
     | 
| 
      
 598 
     | 
    
         
            +
                  #   add_belongs_to(:products, :supplier, polymorphic: true)
         
     | 
| 
      
 599 
     | 
    
         
            +
                  #
         
     | 
| 
      
 600 
     | 
    
         
            +
                  # ====== Create a supplier_id, supplier_type columns and appropriate index
         
     | 
| 
      
 601 
     | 
    
         
            +
                  #
         
     | 
| 
      
 602 
     | 
    
         
            +
                  #   add_reference(:products, :supplier, polymorphic: true, index: true)
         
     | 
| 
      
 603 
     | 
    
         
            +
                  #
         
     | 
| 
      
 604 
     | 
    
         
            +
                  def add_reference(table_name, ref_name, options = {})
         
     | 
| 
      
 605 
     | 
    
         
            +
                    polymorphic = options.delete(:polymorphic)
         
     | 
| 
      
 606 
     | 
    
         
            +
                    index_options = options.delete(:index)
         
     | 
| 
      
 607 
     | 
    
         
            +
                    add_column(table_name, "#{ref_name}_id", :integer, options)
         
     | 
| 
      
 608 
     | 
    
         
            +
                    add_column(table_name, "#{ref_name}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic
         
     | 
| 
      
 609 
     | 
    
         
            +
                    add_index(table_name, polymorphic ? %w[id type].map{ |t| "#{ref_name}_#{t}" } : "#{ref_name}_id", index_options.is_a?(Hash) ? index_options : nil) if index_options
         
     | 
| 
       412 
610 
     | 
    
         
             
                  end
         
     | 
| 
      
 611 
     | 
    
         
            +
                  alias :add_belongs_to :add_reference
         
     | 
| 
      
 612 
     | 
    
         
            +
             
     | 
| 
      
 613 
     | 
    
         
            +
                  # Removes the reference(s). Also removes a +type+ column if one exists.
         
     | 
| 
      
 614 
     | 
    
         
            +
                  # <tt>remove_reference</tt>, <tt>remove_references</tt> and <tt>remove_belongs_to</tt> are acceptable.
         
     | 
| 
      
 615 
     | 
    
         
            +
                  #
         
     | 
| 
      
 616 
     | 
    
         
            +
                  # ====== Remove the reference
         
     | 
| 
      
 617 
     | 
    
         
            +
                  #
         
     | 
| 
      
 618 
     | 
    
         
            +
                  #   remove_reference(:products, :user, index: true)
         
     | 
| 
      
 619 
     | 
    
         
            +
                  #
         
     | 
| 
      
 620 
     | 
    
         
            +
                  # ====== Remove polymorphic reference
         
     | 
| 
      
 621 
     | 
    
         
            +
                  #
         
     | 
| 
      
 622 
     | 
    
         
            +
                  #   remove_reference(:products, :supplier, polymorphic: true)
         
     | 
| 
      
 623 
     | 
    
         
            +
                  #
         
     | 
| 
      
 624 
     | 
    
         
            +
                  def remove_reference(table_name, ref_name, options = {})
         
     | 
| 
      
 625 
     | 
    
         
            +
                    remove_column(table_name, "#{ref_name}_id")
         
     | 
| 
      
 626 
     | 
    
         
            +
                    remove_column(table_name, "#{ref_name}_type") if options[:polymorphic]
         
     | 
| 
      
 627 
     | 
    
         
            +
                  end
         
     | 
| 
      
 628 
     | 
    
         
            +
                  alias :remove_belongs_to :remove_reference
         
     | 
| 
       413 
629 
     | 
    
         | 
| 
       414 
630 
     | 
    
         
             
                  def dump_schema_information #:nodoc:
         
     | 
| 
       415 
631 
     | 
    
         
             
                    sm_table = ActiveRecord::Migrator.schema_migrations_table_name
         
     | 
| 
       416 
     | 
    
         
            -
             
     | 
| 
       417 
     | 
    
         
            -
                     
     | 
| 
      
 632 
     | 
    
         
            +
             
     | 
| 
      
 633 
     | 
    
         
            +
                    ActiveRecord::SchemaMigration.order('version').map { |sm|
         
     | 
| 
      
 634 
     | 
    
         
            +
                      "INSERT INTO #{sm_table} (version) VALUES ('#{sm.version}');"
         
     | 
| 
      
 635 
     | 
    
         
            +
                    }.join "\n\n"
         
     | 
| 
       418 
636 
     | 
    
         
             
                  end
         
     | 
| 
       419 
637 
     | 
    
         | 
| 
       420 
638 
     | 
    
         
             
                  # Should not be called normally, but this operation is non-destructive.
         
     | 
| 
       421 
639 
     | 
    
         
             
                  # The migrations module handles this automatically.
         
     | 
| 
       422 
640 
     | 
    
         
             
                  def initialize_schema_migrations_table
         
     | 
| 
       423 
     | 
    
         
            -
                     
     | 
| 
       424 
     | 
    
         
            -
             
     | 
| 
       425 
     | 
    
         
            -
                    unless table_exists?(sm_table)
         
     | 
| 
       426 
     | 
    
         
            -
                      create_table(sm_table, :id => false) do |schema_migrations_table|
         
     | 
| 
       427 
     | 
    
         
            -
                        schema_migrations_table.column :version, :string, :null => false
         
     | 
| 
       428 
     | 
    
         
            -
                      end
         
     | 
| 
       429 
     | 
    
         
            -
                      add_index sm_table, :version, :unique => true,
         
     | 
| 
       430 
     | 
    
         
            -
                        :name => "#{Base.table_name_prefix}unique_schema_migrations#{Base.table_name_suffix}"
         
     | 
| 
       431 
     | 
    
         
            -
             
     | 
| 
       432 
     | 
    
         
            -
                      # Backwards-compatibility: if we find schema_info, assume we've
         
     | 
| 
       433 
     | 
    
         
            -
                      # migrated up to that point:
         
     | 
| 
       434 
     | 
    
         
            -
                      si_table = Base.table_name_prefix + 'schema_info' + Base.table_name_suffix
         
     | 
| 
       435 
     | 
    
         
            -
             
     | 
| 
       436 
     | 
    
         
            -
                      if table_exists?(si_table)
         
     | 
| 
       437 
     | 
    
         
            -
                        ActiveSupport::Deprecation.warn "Usage of the schema table `#{si_table}` is deprecated. Please switch to using `schema_migrations` table"
         
     | 
| 
       438 
     | 
    
         
            -
             
     | 
| 
       439 
     | 
    
         
            -
                        old_version = select_value("SELECT version FROM #{quote_table_name(si_table)}").to_i
         
     | 
| 
       440 
     | 
    
         
            -
                        assume_migrated_upto_version(old_version)
         
     | 
| 
       441 
     | 
    
         
            -
                        drop_table(si_table)
         
     | 
| 
       442 
     | 
    
         
            -
                      end
         
     | 
| 
       443 
     | 
    
         
            -
                    end
         
     | 
| 
      
 641 
     | 
    
         
            +
                    ActiveRecord::SchemaMigration.create_table
         
     | 
| 
       444 
642 
     | 
    
         
             
                  end
         
     | 
| 
       445 
643 
     | 
    
         | 
| 
       446 
644 
     | 
    
         
             
                  def assume_migrated_upto_version(version, migrations_paths = ActiveRecord::Migrator.migrations_paths)
         
     | 
| 
       447 
     | 
    
         
            -
                    migrations_paths = Array 
     | 
| 
      
 645 
     | 
    
         
            +
                    migrations_paths = Array(migrations_paths)
         
     | 
| 
       448 
646 
     | 
    
         
             
                    version = version.to_i
         
     | 
| 
       449 
647 
     | 
    
         
             
                    sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)
         
     | 
| 
       450 
648 
     | 
    
         | 
| 
         @@ -483,7 +681,7 @@ module ActiveRecord 
     | 
|
| 
       483 
681 
     | 
    
         
             
                            column_type_sql << "(#{precision})"
         
     | 
| 
       484 
682 
     | 
    
         
             
                          end
         
     | 
| 
       485 
683 
     | 
    
         
             
                        elsif scale
         
     | 
| 
       486 
     | 
    
         
            -
                          raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale  
     | 
| 
      
 684 
     | 
    
         
            +
                          raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale is specified"
         
     | 
| 
       487 
685 
     | 
    
         
             
                        end
         
     | 
| 
       488 
686 
     | 
    
         | 
| 
       489 
687 
     | 
    
         
             
                      elsif (type != :primary_key) && (limit ||= native.is_a?(Hash) && native[:limit])
         
     | 
| 
         @@ -492,7 +690,7 @@ module ActiveRecord 
     | 
|
| 
       492 
690 
     | 
    
         | 
| 
       493 
691 
     | 
    
         
             
                      column_type_sql
         
     | 
| 
       494 
692 
     | 
    
         
             
                    else
         
     | 
| 
       495 
     | 
    
         
            -
                      type
         
     | 
| 
      
 693 
     | 
    
         
            +
                      type.to_s
         
     | 
| 
       496 
694 
     | 
    
         
             
                    end
         
     | 
| 
       497 
695 
     | 
    
         
             
                  end
         
     | 
| 
       498 
696 
     | 
    
         | 
| 
         @@ -502,38 +700,57 @@ module ActiveRecord 
     | 
|
| 
       502 
700 
     | 
    
         
             
                    if options[:null] == false
         
     | 
| 
       503 
701 
     | 
    
         
             
                      sql << " NOT NULL"
         
     | 
| 
       504 
702 
     | 
    
         
             
                    end
         
     | 
| 
      
 703 
     | 
    
         
            +
                    if options[:auto_increment] == true
         
     | 
| 
      
 704 
     | 
    
         
            +
                      sql << " AUTO_INCREMENT"
         
     | 
| 
      
 705 
     | 
    
         
            +
                    end
         
     | 
| 
       505 
706 
     | 
    
         
             
                  end
         
     | 
| 
       506 
707 
     | 
    
         | 
| 
       507 
708 
     | 
    
         
             
                  # SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
         
     | 
| 
       508 
     | 
    
         
            -
                  # Both PostgreSQL and Oracle overrides this for custom DISTINCT syntax.
         
     | 
| 
       509 
709 
     | 
    
         
             
                  #
         
     | 
| 
       510 
     | 
    
         
            -
                  #   distinct("posts.id", "posts.created_at desc")
         
     | 
| 
      
 710 
     | 
    
         
            +
                  #   distinct("posts.id", ["posts.created_at desc"])
         
     | 
| 
      
 711 
     | 
    
         
            +
                  #
         
     | 
| 
       511 
712 
     | 
    
         
             
                  def distinct(columns, order_by)
         
     | 
| 
       512 
     | 
    
         
            -
                    " 
     | 
| 
      
 713 
     | 
    
         
            +
                    ActiveSupport::Deprecation.warn("#distinct is deprecated and shall be removed from future releases.")
         
     | 
| 
      
 714 
     | 
    
         
            +
                    "DISTINCT #{columns_for_distinct(columns, order_by)}"
         
     | 
| 
       513 
715 
     | 
    
         
             
                  end
         
     | 
| 
       514 
716 
     | 
    
         | 
| 
       515 
     | 
    
         
            -
                  #  
     | 
| 
       516 
     | 
    
         
            -
                  #  
     | 
| 
       517 
     | 
    
         
            -
                  # 
     | 
| 
       518 
     | 
    
         
            -
                   
     | 
| 
       519 
     | 
    
         
            -
             
     | 
| 
       520 
     | 
    
         
            -
             
     | 
| 
      
 717 
     | 
    
         
            +
                  # Given a set of columns and an ORDER BY clause, returns the columns for a SELECT DISTINCT.
         
     | 
| 
      
 718 
     | 
    
         
            +
                  # Both PostgreSQL and Oracle overrides this for custom DISTINCT syntax - they
         
     | 
| 
      
 719 
     | 
    
         
            +
                  # require the order columns appear in the SELECT.
         
     | 
| 
      
 720 
     | 
    
         
            +
                  #
         
     | 
| 
      
 721 
     | 
    
         
            +
                  #   columns_for_distinct("posts.id", ["posts.created_at desc"])
         
     | 
| 
      
 722 
     | 
    
         
            +
                  def columns_for_distinct(columns, orders) #:nodoc:
         
     | 
| 
      
 723 
     | 
    
         
            +
                    columns
         
     | 
| 
       521 
724 
     | 
    
         
             
                  end
         
     | 
| 
       522 
725 
     | 
    
         | 
| 
       523 
     | 
    
         
            -
                  #  
     | 
| 
       524 
     | 
    
         
            -
                  # 
     | 
| 
      
 726 
     | 
    
         
            +
                  # Adds timestamps (+created_at+ and +updated_at+) columns to the named table.
         
     | 
| 
      
 727 
     | 
    
         
            +
                  #
         
     | 
| 
      
 728 
     | 
    
         
            +
                  #   add_timestamps(:suppliers)
         
     | 
| 
      
 729 
     | 
    
         
            +
                  #
         
     | 
| 
      
 730 
     | 
    
         
            +
                  def add_timestamps(table_name, options = {})
         
     | 
| 
      
 731 
     | 
    
         
            +
                    add_column table_name, :created_at, :datetime, options
         
     | 
| 
      
 732 
     | 
    
         
            +
                    add_column table_name, :updated_at, :datetime, options
         
     | 
| 
      
 733 
     | 
    
         
            +
                  end
         
     | 
| 
      
 734 
     | 
    
         
            +
             
     | 
| 
      
 735 
     | 
    
         
            +
                  # Removes the timestamp columns (+created_at+ and +updated_at+) from the table definition.
         
     | 
| 
      
 736 
     | 
    
         
            +
                  #
         
     | 
| 
       525 
737 
     | 
    
         
             
                  #  remove_timestamps(:suppliers)
         
     | 
| 
      
 738 
     | 
    
         
            +
                  #
         
     | 
| 
       526 
739 
     | 
    
         
             
                  def remove_timestamps(table_name)
         
     | 
| 
       527 
740 
     | 
    
         
             
                    remove_column table_name, :updated_at
         
     | 
| 
       528 
741 
     | 
    
         
             
                    remove_column table_name, :created_at
         
     | 
| 
       529 
742 
     | 
    
         
             
                  end
         
     | 
| 
       530 
743 
     | 
    
         | 
| 
      
 744 
     | 
    
         
            +
                  def update_table_definition(table_name, base) #:nodoc:
         
     | 
| 
      
 745 
     | 
    
         
            +
                    Table.new(table_name, base)
         
     | 
| 
      
 746 
     | 
    
         
            +
                  end
         
     | 
| 
      
 747 
     | 
    
         
            +
             
     | 
| 
       531 
748 
     | 
    
         
             
                  protected
         
     | 
| 
       532 
749 
     | 
    
         
             
                    def add_index_sort_order(option_strings, column_names, options = {})
         
     | 
| 
       533 
750 
     | 
    
         
             
                      if options.is_a?(Hash) && order = options[:order]
         
     | 
| 
       534 
751 
     | 
    
         
             
                        case order
         
     | 
| 
       535 
752 
     | 
    
         
             
                        when Hash
         
     | 
| 
       536 
     | 
    
         
            -
                          column_names.each {|name| option_strings[name] += " #{order[name]. 
     | 
| 
      
 753 
     | 
    
         
            +
                          column_names.each {|name| option_strings[name] += " #{order[name].upcase}" if order.has_key?(name)}
         
     | 
| 
       537 
754 
     | 
    
         
             
                        when String
         
     | 
| 
       538 
755 
     | 
    
         
             
                          column_names.each {|name| option_strings[name] += " #{order.upcase}"}
         
     | 
| 
       539 
756 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -559,31 +776,65 @@ module ActiveRecord 
     | 
|
| 
       559 
776 
     | 
    
         
             
                    end
         
     | 
| 
       560 
777 
     | 
    
         | 
| 
       561 
778 
     | 
    
         
             
                    def add_index_options(table_name, column_name, options = {})
         
     | 
| 
       562 
     | 
    
         
            -
                      column_names = Array 
     | 
| 
       563 
     | 
    
         
            -
                      index_name   = index_name(table_name, : 
     | 
| 
      
 779 
     | 
    
         
            +
                      column_names = Array(column_name)
         
     | 
| 
      
 780 
     | 
    
         
            +
                      index_name   = index_name(table_name, column: column_names)
         
     | 
| 
       564 
781 
     | 
    
         | 
| 
       565 
782 
     | 
    
         
             
                      if Hash === options # legacy support, since this param was a string
         
     | 
| 
      
 783 
     | 
    
         
            +
                        options.assert_valid_keys(:unique, :order, :name, :where, :length, :internal, :using, :algorithm, :type)
         
     | 
| 
      
 784 
     | 
    
         
            +
             
     | 
| 
       566 
785 
     | 
    
         
             
                        index_type = options[:unique] ? "UNIQUE" : ""
         
     | 
| 
      
 786 
     | 
    
         
            +
                        index_type = options[:type].to_s if options.key?(:type)
         
     | 
| 
       567 
787 
     | 
    
         
             
                        index_name = options[:name].to_s if options.key?(:name)
         
     | 
| 
      
 788 
     | 
    
         
            +
                        max_index_length = options.fetch(:internal, false) ? index_name_length : allowed_index_name_length
         
     | 
| 
      
 789 
     | 
    
         
            +
             
     | 
| 
      
 790 
     | 
    
         
            +
                        if options.key?(:algorithm)
         
     | 
| 
      
 791 
     | 
    
         
            +
                          algorithm = index_algorithms.fetch(options[:algorithm]) {
         
     | 
| 
      
 792 
     | 
    
         
            +
                            raise ArgumentError.new("Algorithm must be one of the following: #{index_algorithms.keys.map(&:inspect).join(', ')}")
         
     | 
| 
      
 793 
     | 
    
         
            +
                          }
         
     | 
| 
      
 794 
     | 
    
         
            +
                        end
         
     | 
| 
      
 795 
     | 
    
         
            +
             
     | 
| 
      
 796 
     | 
    
         
            +
                        using = "USING #{options[:using]}" if options[:using].present?
         
     | 
| 
      
 797 
     | 
    
         
            +
             
     | 
| 
      
 798 
     | 
    
         
            +
                        if supports_partial_index?
         
     | 
| 
      
 799 
     | 
    
         
            +
                          index_options = options[:where] ? " WHERE #{options[:where]}" : ""
         
     | 
| 
      
 800 
     | 
    
         
            +
                        end
         
     | 
| 
       568 
801 
     | 
    
         
             
                      else
         
     | 
| 
      
 802 
     | 
    
         
            +
                        if options
         
     | 
| 
      
 803 
     | 
    
         
            +
                          message = "Passing a string as third argument of `add_index` is deprecated and will" +
         
     | 
| 
      
 804 
     | 
    
         
            +
                            " be removed in Rails 4.1." +
         
     | 
| 
      
 805 
     | 
    
         
            +
                            " Use add_index(#{table_name.inspect}, #{column_name.inspect}, unique: true) instead"
         
     | 
| 
      
 806 
     | 
    
         
            +
             
     | 
| 
      
 807 
     | 
    
         
            +
                          ActiveSupport::Deprecation.warn message
         
     | 
| 
      
 808 
     | 
    
         
            +
                        end
         
     | 
| 
      
 809 
     | 
    
         
            +
             
     | 
| 
       569 
810 
     | 
    
         
             
                        index_type = options
         
     | 
| 
      
 811 
     | 
    
         
            +
                        max_index_length = allowed_index_name_length
         
     | 
| 
      
 812 
     | 
    
         
            +
                        algorithm = using = nil
         
     | 
| 
       570 
813 
     | 
    
         
             
                      end
         
     | 
| 
       571 
814 
     | 
    
         | 
| 
       572 
     | 
    
         
            -
                      if index_name.length >  
     | 
| 
       573 
     | 
    
         
            -
                        raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{ 
     | 
| 
      
 815 
     | 
    
         
            +
                      if index_name.length > max_index_length
         
     | 
| 
      
 816 
     | 
    
         
            +
                        raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{max_index_length} characters"
         
     | 
| 
       574 
817 
     | 
    
         
             
                      end
         
     | 
| 
       575 
818 
     | 
    
         
             
                      if index_name_exists?(table_name, index_name, false)
         
     | 
| 
       576 
819 
     | 
    
         
             
                        raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists"
         
     | 
| 
       577 
820 
     | 
    
         
             
                      end
         
     | 
| 
       578 
821 
     | 
    
         
             
                      index_columns = quoted_columns_for_index(column_names, options).join(", ")
         
     | 
| 
       579 
822 
     | 
    
         | 
| 
       580 
     | 
    
         
            -
                      [index_name, index_type, index_columns]
         
     | 
| 
      
 823 
     | 
    
         
            +
                      [index_name, index_type, index_columns, index_options, algorithm, using]
         
     | 
| 
       581 
824 
     | 
    
         
             
                    end
         
     | 
| 
       582 
825 
     | 
    
         | 
| 
       583 
826 
     | 
    
         
             
                    def index_name_for_remove(table_name, options = {})
         
     | 
| 
       584 
827 
     | 
    
         
             
                      index_name = index_name(table_name, options)
         
     | 
| 
       585 
828 
     | 
    
         | 
| 
       586 
829 
     | 
    
         
             
                      unless index_name_exists?(table_name, index_name, true)
         
     | 
| 
      
 830 
     | 
    
         
            +
                        if options.is_a?(Hash) && options.has_key?(:name)
         
     | 
| 
      
 831 
     | 
    
         
            +
                          options_without_column = options.dup
         
     | 
| 
      
 832 
     | 
    
         
            +
                          options_without_column.delete :column
         
     | 
| 
      
 833 
     | 
    
         
            +
                          index_name_without_column = index_name(table_name, options_without_column)
         
     | 
| 
      
 834 
     | 
    
         
            +
             
     | 
| 
      
 835 
     | 
    
         
            +
                          return index_name_without_column if index_name_exists?(table_name, index_name_without_column, false)
         
     | 
| 
      
 836 
     | 
    
         
            +
                        end
         
     | 
| 
      
 837 
     | 
    
         
            +
             
     | 
| 
       587 
838 
     | 
    
         
             
                        raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist"
         
     | 
| 
       588 
839 
     | 
    
         
             
                      end
         
     | 
| 
       589 
840 
     | 
    
         | 
| 
         @@ -591,15 +842,46 @@ module ActiveRecord 
     | 
|
| 
       591 
842 
     | 
    
         
             
                    end
         
     | 
| 
       592 
843 
     | 
    
         | 
| 
       593 
844 
     | 
    
         
             
                    def columns_for_remove(table_name, *column_names)
         
     | 
| 
       594 
     | 
    
         
            -
                       
     | 
| 
       595 
     | 
    
         
            -
             
     | 
| 
       596 
     | 
    
         
            -
                      raise ArgumentError.new("You must specify at least one column name. Example: remove_column(:people, :first_name)") if column_names.blank?
         
     | 
| 
      
 845 
     | 
    
         
            +
                      ActiveSupport::Deprecation.warn("columns_for_remove is deprecated and will be removed in the future")
         
     | 
| 
      
 846 
     | 
    
         
            +
                      raise ArgumentError.new("You must specify at least one column name. Example: remove_columns(:people, :first_name)") if column_names.blank?
         
     | 
| 
       597 
847 
     | 
    
         
             
                      column_names.map {|column_name| quote_column_name(column_name) }
         
     | 
| 
       598 
848 
     | 
    
         
             
                    end
         
     | 
| 
       599 
849 
     | 
    
         | 
| 
      
 850 
     | 
    
         
            +
                    def rename_table_indexes(table_name, new_name)
         
     | 
| 
      
 851 
     | 
    
         
            +
                      indexes(new_name).each do |index|
         
     | 
| 
      
 852 
     | 
    
         
            +
                        generated_index_name = index_name(table_name, column: index.columns)
         
     | 
| 
      
 853 
     | 
    
         
            +
                        if generated_index_name == index.name
         
     | 
| 
      
 854 
     | 
    
         
            +
                          rename_index new_name, generated_index_name, index_name(new_name, column: index.columns)
         
     | 
| 
      
 855 
     | 
    
         
            +
                        end
         
     | 
| 
      
 856 
     | 
    
         
            +
                      end
         
     | 
| 
      
 857 
     | 
    
         
            +
                    end
         
     | 
| 
      
 858 
     | 
    
         
            +
             
     | 
| 
      
 859 
     | 
    
         
            +
                    def rename_column_indexes(table_name, column_name, new_column_name)
         
     | 
| 
      
 860 
     | 
    
         
            +
                      column_name, new_column_name = column_name.to_s, new_column_name.to_s
         
     | 
| 
      
 861 
     | 
    
         
            +
                      indexes(table_name).each do |index|
         
     | 
| 
      
 862 
     | 
    
         
            +
                        next unless index.columns.include?(new_column_name)
         
     | 
| 
      
 863 
     | 
    
         
            +
                        old_columns = index.columns.dup
         
     | 
| 
      
 864 
     | 
    
         
            +
                        old_columns[old_columns.index(new_column_name)] = column_name
         
     | 
| 
      
 865 
     | 
    
         
            +
                        generated_index_name = index_name(table_name, column: old_columns)
         
     | 
| 
      
 866 
     | 
    
         
            +
                        if generated_index_name == index.name
         
     | 
| 
      
 867 
     | 
    
         
            +
                          rename_index table_name, generated_index_name, index_name(table_name, column: index.columns)
         
     | 
| 
      
 868 
     | 
    
         
            +
                        end
         
     | 
| 
      
 869 
     | 
    
         
            +
                      end
         
     | 
| 
      
 870 
     | 
    
         
            +
                    end
         
     | 
| 
      
 871 
     | 
    
         
            +
             
     | 
| 
      
 872 
     | 
    
         
            +
                    def quote_value(value, column)
         
     | 
| 
      
 873 
     | 
    
         
            +
                      column.sql_type ||= type_to_sql(column.type, column.limit, column.precision, column.scale)
         
     | 
| 
      
 874 
     | 
    
         
            +
             
     | 
| 
      
 875 
     | 
    
         
            +
                      quote(value, column)
         
     | 
| 
      
 876 
     | 
    
         
            +
                    end
         
     | 
| 
      
 877 
     | 
    
         
            +
             
     | 
| 
       600 
878 
     | 
    
         
             
                  private
         
     | 
| 
       601 
     | 
    
         
            -
                  def  
     | 
| 
       602 
     | 
    
         
            -
                    TableDefinition.new 
     | 
| 
      
 879 
     | 
    
         
            +
                  def create_table_definition(name, temporary, options)
         
     | 
| 
      
 880 
     | 
    
         
            +
                    TableDefinition.new native_database_types, name, temporary, options
         
     | 
| 
      
 881 
     | 
    
         
            +
                  end
         
     | 
| 
      
 882 
     | 
    
         
            +
             
     | 
| 
      
 883 
     | 
    
         
            +
                  def create_alter_table(name)
         
     | 
| 
      
 884 
     | 
    
         
            +
                    AlterTable.new create_table_definition(name, false, {})
         
     | 
| 
       603 
885 
     | 
    
         
             
                  end
         
     | 
| 
       604 
886 
     | 
    
         
             
                end
         
     | 
| 
       605 
887 
     | 
    
         
             
              end
         
     |