Пользовательский тип базы данных в ActiveRecord
Я использую Rails 3.1.1 с PostgreSQL 9.1 и модулем earthdistance. Чтобы правильно рассчитать расстояние между различными точками, я настроил столбец с earth
введите мой branches
Таблица.
Проблема, с которой я сейчас сталкиваюсь, состоит в том, что мое Rails-приложение, которое использует эту таблицу, не понимает тип земли, и поэтому я получаю это в своем db/schema.rb
:
# Не удалось создать дамп "ветвей" таблицы из-за следующей ошибки StandardError # Неизвестный тип 'земля' для столбца 'местоположение'
Это проблематично, поскольку теперь я не могу создать свою тестовую базу данных из schema.rb.
Как я могу добавить этот тип в AR или заставить его игнорировать этот столбец?
2 ответа
Попробуй это:
Измените свой config/application.rb
config.active_record.schema_format = :sql
Это изменит выходной формат на собственный формат PostgreSQL SQL, schema.rb будет отключен и будет создан новый файл /db/config/structure.sql
Другой случай, когда кто-то может столкнуться с этим, - это вставка ваших пользовательских типов (перечислений) postgres в postgresql. Если вы делаете это и по-прежнему хотите использовать Ruby для вашего schema.rb, вы можете добавить пользовательские типы баз данных в список допустимых типов адаптера.
Например, скажем, у вас есть миграция, как это, с address_type
а также address_status
,
class CreateAddresses < ActiveRecord::Migration
def up
execute <<-SQL
CREATE TYPE address_status AS ENUM ('active', 'archived');
CREATE TYPE address_type AS ENUM ('billing', 'shipping');
SQL
create_table :customer_addresses do |t|
# bla bla
t.column :address_type, :address_type
t.column :status, :address_status
t.timestamps null: false
end
end
def down
drop_table :customer_addresses
execute <<-SQL
DROP TYPE address_type;
DROP TYPE address_status;
SQL
end
end
Затем создайте инициализатор или добавьте нечто подобное в ваш application.rb:
# config/initializers/postres_enum_custom_types.rb
module ActiveRecord
module ConnectionAdapters
if const_defined?(:PostgreSQLAdapter)
class PostgreSQLAdapter
NATIVE_DATABASE_TYPES.merge!(
address_status: { name: 'character varying' },
address_type: { name: 'character varying' }
)
end
end
end
end
Примечания о моем решении:
- Я проверяю существование
PostgreSQLAdpater
из-за того, что гем статического анализа, который я использую, частично загружает некоторые зависимости AR - в частности, гемannotate
, - Источник для оригинального определения здесь.
Предыстория моего столкновения с этим: когда это случилось со мной в rails 5.0.x, миграция прошла нормально, но тогда моя тестовая среда потерпела неудачу при попытке запустить db:test:prepare
или же db:reset
, Мне потребовалось много времени, чтобы отследить это до проблемы с дампом схемы.
Для всех, кто заходит на эту страницу, кто-то реализовал это в виде простого в использовании драгоценного камня.
Так будут выглядеть файлы миграции и модели соответственно
# migration
class CreatePerson < ActiveRecord::Migration
def change
create_enum :mood, %w(happy great never_better)
create_table :person do |t|
t.enum :person_mood, enum_name: :mood
end
end
end
# model
class Person < ActiveRecord::Base
enum mood: { happy: 'happy', great: 'great', never_better: 'never_better' }
end