誰かがこれに遭遇する可能性があるもう1つのケースは、カスタムタイプ(列挙型)をPostgreSQLに挿入する場合です。これを実行してもSQLダンパーを使用せずにschema.rbをダンプしたい場合は、カスタムデータベースタイプをアダプターの有効なタイプのリストに追加できます。
アップデート2021-08-13:コメント投稿者は、以下の私の提案よりも簡単な方法があるかもしれないと指摘しています。
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:my_custom_type] = { name: "my_custom_type_name" }
元の提案
たとえば、とがCustomer
あり、postgresのネイティブ列挙型を使用したいとしますstatus
。priority
移行では手動でセットアップを行う必要があり、Railsがスキーマを生成するのに役立つ初期化子が必要になります。
移行
class CreateCustomers < ActiveRecord::Migration[5.2]
def up
execute <<-SQL
CREATE TYPE type_status AS ENUM ('active', 'inactive');
CREATE TYPE type_priority AS ENUM ('high', 'medium','low');
SQL
create_table :customers do |t|
t.string :name
t.column :status, :type_status
t.column :priority, :type_priority
end
end
def down
drop_table :customer_addresses
execute <<-SQL
DROP TYPE status;
DROP TYPE priority;
SQL
end
end
イニシャライザ。
# config/initializers/postres_custom_enum_types.rb
# Following only needed if the adapater isn't loaded for some reason - e.g.
# if you have no models in your app.
require "active_record/connection_adapters/postgresql_adapter"
module ActiveRecord
module ConnectionAdapters
if const_defined?(:PostgreSQLAdapter)
class PostgreSQLAdapter
NATIVE_DATABASE_TYPES.merge!(
enum: { name: 'enum' },
# there is a chance the above causes conflicts in some cases, you can
# always be more explicit and actually use your type or names (I am not looking up which)
# type_priority: { name: 'enum' }
)
end
end
end
end
このソリューションの検証
これは、DBに表示されるものです。
enum_in_db_development=# INSERT INTO customers VALUES (1, 'Mario','active','high');
INSERT 0 1
enum_in_db_development=# INSERT INTO customers VALUES (1, 'Mario','active','notthere');
ERROR: invalid input value for enum type_priority: "nothere"
LINE 1: INSERT INTO customers VALUES (1, 'Mario','active','notthere')
^
enum_in_db_development=# SELECT enum_range(NULL::type_priority);
enum_range
-------------------
{high,medium,low}
(1 row)
私の解決策についてのメモ:
PostgreSQLAdpater
私が使用している静的分析gemがいくつかのAR依存関係(特にgem)を部分的にロードする方法のために、存在を確認していますannotate
。
- NATIVE_DATABASE_TYPESの元の定義のソースは、rails6用です。
これに遭遇した背景:Rails 5.0.xでこれが発生した場合、移行は正常に実行されましdb:test:prepare
たが、またはを実行しようとするとテスト環境が失敗しましたdb:reset
。これをスキーマダンプの問題まで追跡するのにかなりの時間がかかりました。