Rails Admin 3.1.2访问含PostgreSQL timestamptz字段模型时报错
Rails Admin 3.1.2 兼容PostgreSQL timestamptz字段的解决方案
问题场景
使用Rails Admin 3.1.2访问包含timestamp with time zone(timestamptz)字段的PostgreSQL表时,控制台抛出错误:
Unsupported field datatype: timestamptz
错误回溯信息:
rails_admin (3.1.2) lib/rails_admin/config/fields/types.rb:14:in `block in load' rails_admin (3.1.2) lib/rails_admin/config/fields/types.rb:14:in `fetch' rails_admin (3.1.2) lib/rails_admin/config/fields/types.rb:14:in `load' rails_admin (3.1.2) lib/rails_admin/config/fields.rb:17:in `block in <module:Fields>' rails_admin (3.1.2) lib/rails_admin/config/fields.rb:57:in `block (2 levels) in factory' rails_admin (3.1.2) lib/rails_admin/config/fields.rb:57:in `each' rails_admin (3.1.2) lib/rails_admin/config/fields.rb:57:in `detect' rails_admin (3.1.2) lib/rails_admin/config/fields.rb:57:in `block in factory' rails_admin (3.1.2) lib/rails_admin/config/fields.rb:52:in `each' rails_admin (3.1.2) lib/rails_admin/config/fields.rb:52:in `factory' rails_admin (3.1.2) lib/rails_admin/config/has_fields.rb:135:in `_fields' rails_admin (3.1.2) lib/rails_admin/config/has_fields.rb:138:in `_fields' rails_admin (3.1.2) lib/rails_admin/config/has_fields.rb:109:in `all_fields' rails_admin (3.1.2) lib/rails_admin/config/has_fields.rb:84:in `fields' rails_admin (3.1.2) app/controllers/rails_admin/main_controller.rb:127:in `get_collection'
技术栈信息
- Rails 7.0.4.3
- Ruby 3.1.3
- gem rails_admin 3.1.2
- gem pg 1.4.6
- PostgreSQL 12.9
上下文说明
- 将字段改为
timestamp without time zone可正常运行,但业务需要时区支持; - 旧版本组合(Rails Admin 2 + Rails 5)支持该类型;
- Rails Admin的类型注册表中仅存在
:timestamp键,无:timestamptz键。
相关代码与表定义
PostgreSQL表定义:
CREATE TABLE public.clients ( id integer NOT NULL, name character varying(100) NOT NULL, created_at timestamp with time zone DEFAULT now(), updated_at timestamp with time zone, slug character varying(100) NOT NULL );
Client模型定义:
class Client < ApplicationRecord end
解决方案
方法1:全局注册timestamptz到timestamp类型映射
在项目初始化文件(如config/initializers/rails_admin.rb)中添加配置,让Rails Admin将timestamptz字段识别为已支持的timestamp类型:
RailsAdmin.config do |config| # 其他原有配置... # 全局映射timestamptz字段为timestamp类型 config.model '*' do configure :created_at, :timestamp configure :updated_at, :timestamp # 如有自定义timestamptz字段,需额外添加配置 # configure :your_custom_timestamptz_field, :timestamp end end
更通用的全局注册方式:
# config/initializers/rails_admin_timestamptz.rb require 'rails_admin/config/fields/types' RailsAdmin::Config::Fields::Types::register(:timestamptz, RailsAdmin::Config::Fields::Types::Timestamp)
方法2:针对单个模型配置字段类型
若仅需特定模型支持timestamptz,可在Rails Admin配置中单独指定字段类型:
# config/initializers/rails_admin.rb RailsAdmin.config do |config| config.model 'Client' do list do fields :id, :name, :created_at, :updated_at, :slug configure :created_at, :timestamp configure :updated_at, :timestamp end edit do fields :name, :created_at, :updated_at, :slug configure :created_at, :timestamp configure :updated_at, :timestamp end end end
方法3:自定义timestamptz字段类型(可选)
如果需要对timestamptz字段做特殊逻辑处理,可自定义字段类型继承现有Timestamp类型:
# app/rails_admin/fields/types/timestamptz.rb module RailsAdmin module Config module Fields module Types class Timestamptz < RailsAdmin::Config::Fields::Types::Timestamp RailsAdmin::Config::Fields::Types::register(:timestamptz, self) end end end end end
然后在初始化文件中加载该自定义类型:
# config/initializers/rails_admin.rb require Rails.root.join('app/rails_admin/fields/types/timestamptz') RailsAdmin.config do |config| # 其他原有配置... end
内容的提问来源于stack exchange,提问作者Carlos Ochoa
相关产品推荐
相关产品推荐

