ActiveRecord中的自定义数据库类型

Pat*_*ien 11 activerecord ruby-on-rails earthdistance

我正在使用Rails 3.1.1和PostgreSQL 9.1以及地球距离模块.为了能够正确计算不同位置之间的距离,我earthbranches表格中设置了一个类型的列.

我现在遇到的问题是我的Rails应用程序使用此表不理解地球类型,因此我得到了这个db/schema.rb:

# Could not dump table "branches" because of following StandardError
#   Unknown type 'earth' for column 'location'

这是有问题的,因为现在我无法从schema.rb创建我的测试数据库.

如何将此类型添加到AR或使其忽略该列?

Mar*_*res 15

有人可能遇到这种情况的另一种情况是将自定义postgres类型(枚举)插入postgresql.如果这样做并且仍然希望将Ruby用于schema.rb,则可以将自定义数据库类型添加到适配器的有效类型列表中.

例如,假设您有一个类似的迁移,使用address_typeaddress_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
Run Code Online (Sandbox Code Playgroud)

然后在创建初始化程序或向您的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
Run Code Online (Sandbox Code Playgroud)

关于我解决方案的说明

  • 我正在检查是否存在PostgreSQLAdpater因为我正在使用的静态分析gem部分加载一些AR依赖项 - 特别是gem annotate.
  • 原始定义的来源在这里.

我遇到了此背景:当这发生在我身上的轨道5.0.x中的迁移细跑,但随后试图运行时,我的测试环境将失败db:test:preparedb:reset.我花了很长时间才将其跟踪到架构转储问题.


Doc*_*rRu 8

试试这个:

改变你的config/application.rb

config.active_record.schema_format = :sql
Run Code Online (Sandbox Code Playgroud)

这会将输出格式更改为本机PostgreSQL SQL格式,schema.rb将被禁用,并将生成一个新文件/db/config/structure.sql