diff options
author | Carlos Antonio da Silva <carlosantoniodasilva@gmail.com> | 2013-02-28 04:49:47 -0800 |
---|---|---|
committer | Carlos Antonio da Silva <carlosantoniodasilva@gmail.com> | 2013-02-28 04:49:47 -0800 |
commit | 8f6b70f1fd49b8520a744cc90102051043faf315 (patch) | |
tree | 30c2f502ca9c4833e980eabf65b384243f9c1e00 | |
parent | a3894380eb6e94b9d0f240d41dcd4af44f1d1dcf (diff) | |
parent | 5d0ca7462255b7d52a007cfe5bbc7e1bf67c3f79 (diff) | |
download | rails-8f6b70f1fd49b8520a744cc90102051043faf315.tar.gz rails-8f6b70f1fd49b8520a744cc90102051043faf315.tar.bz2 rails-8f6b70f1fd49b8520a744cc90102051043faf315.zip |
Merge pull request #9484 from senny/9480_change_table_and_hstore
Support PostgreSQL specific column types when using `change_table`.
We use `TableDefinition` for `#create_table` and `Table` for `#change_table`.
The PostgreSQL sepcific types were only defined on `TableDefinition` so they needed to be added to `Table` as well.
6 files changed, 67 insertions, 9 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 496f902979..a5d74418c4 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,5 +1,17 @@ ## Rails 4.0.0 (unreleased) ## +* Support PostgreSQL specific column types when using `change_table`. + Fixes #9480. + + Example: + + change_table :authors do |t| + t.hstore :books + t.json :metadata + end + + *Yves Senn* + * Revert 408227d9c5ed7d, 'quote numeric'. This introduced some regressions. *Steve Klabnik* diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index f758e19a4f..42206de8fc 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -44,8 +44,8 @@ module ActiveRecord # Represents the schema of an SQL table in an abstract way. This class # provides methods for manipulating the schema representation. # - # Inside migration files, the +t+ object in +create_table+ and - # +change_table+ is actually of this type: + # Inside migration files, the +t+ object in +create_table+ + # is actually of this type: # # class SomeMigration < ActiveRecord::Migration # def up @@ -489,7 +489,7 @@ module ActiveRecord args.each do |name| @base.add_column(@table_name, name, column_type, options) end - end + end end private diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 9bae880024..0cce8c7596 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -156,7 +156,7 @@ module ActiveRecord # # See also TableDefinition#column for details on how to create columns. def create_table(table_name, options = {}) - td = table_definition + td = create_table_definition td.primary_key(options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)) unless options[:id] == false yield td if block_given? @@ -298,10 +298,10 @@ module ActiveRecord def change_table(table_name, options = {}) if supports_bulk_alter? && options[:bulk] recorder = ActiveRecord::Migration::CommandRecorder.new(self) - yield Table.new(table_name, recorder) + yield update_table_definition(table_name, recorder) bulk_change_table(table_name, recorder.commands) else - yield Table.new(table_name, self) + yield update_table_definition(table_name, self) end end @@ -727,9 +727,13 @@ module ActiveRecord end private - def table_definition + def create_table_definition TableDefinition.new(self) end + + def update_table_definition(table_name, base) + Table.new(table_name, base) + end end end end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 2bb2557efd..b39eb058ae 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -263,7 +263,7 @@ module ActiveRecord attr_accessor :array end - class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition + module ColumnMethods def xml(*args) options = args.extract_options! column(args[0], 'xml', options) @@ -325,6 +325,10 @@ module ActiveRecord def json(name, options = {}) column(name, 'json', options) end + end + + class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition + include ColumnMethods def column(name, type = nil, options = {}) super @@ -344,6 +348,10 @@ module ActiveRecord end end + class Table < ActiveRecord::ConnectionAdapters::Table + include ColumnMethods + end + ADAPTER_NAME = 'PostgreSQL' NATIVE_DATABASE_TYPES = { @@ -884,9 +892,13 @@ module ActiveRecord $1.strip if $1 end - def table_definition + def create_table_definition TableDefinition.new(self) end + + def update_table_definition(table_name, base) + Table.new(table_name, base) + end end end end diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb index 6640f9b497..ad98d7c8ce 100644 --- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb +++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb @@ -65,6 +65,21 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase assert_equal :hstore, @column.type end + def test_change_table_supports_hstore + @connection.transaction do + @connection.change_table('hstores') do |t| + t.hstore 'users', default: '' + end + Hstore.reset_column_information + column = Hstore.columns.find { |c| c.name == 'users' } + assert_equal :hstore, column.type + + raise ActiveRecord::Rollback # reset the schema change + end + ensure + Hstore.reset_column_information + end + def test_type_cast_hstore assert @column diff --git a/activerecord/test/cases/adapters/postgresql/json_test.rb b/activerecord/test/cases/adapters/postgresql/json_test.rb index d64037eec0..6fc08ae4f0 100644 --- a/activerecord/test/cases/adapters/postgresql/json_test.rb +++ b/activerecord/test/cases/adapters/postgresql/json_test.rb @@ -31,6 +31,21 @@ class PostgresqlJSONTest < ActiveRecord::TestCase assert_equal :json, @column.type end + def test_change_table_supports_json + @connection.transaction do + @connection.change_table('json_data_type') do |t| + t.json 'users', default: '{}' + end + JsonDataType.reset_column_information + column = JsonDataType.columns.find { |c| c.name == 'users' } + assert_equal :json, column.type + + raise ActiveRecord::Rollback # reset the schema change + end + ensure + JsonDataType.reset_column_information + end + def test_type_cast_json assert @column |