[Rails] ให้ rails7 ใช้ timestamptz สำหรับ created_at

Teerayut Hiruntaraporn
1 min readAug 28, 2022

--

คนที่ใช้ rails อาจจะพอทราบว่า โดยปกติเวลาที่เราใช้ activerecord กับ postgresql มันจะใช้ Timestamp without timezone ในการจัดเก็บ ซึ่ง by default จะเก็บข้อมูลโดยแปลงเวลาที่ลง database เป็น เวลาที่ utc โดยอัติโนมัติ

อย่างไรก็ตาม ใน activerecord version 7 (จริงๆ น่าจะเริ่มที่ 6.2 แต่ไม่มี release) ได้มีการเพิ่มการใช้งาน timestamp with timezone อย่างสมบูรณ์ ใน activerecord แล้ว โดยใช้ :timestamptz

แม้จะอย่างนั้นก็ตาม แต่ในการสร้าง table model พวกตัวสำคัญเช่น created_at และ updated_at ก็ยังไม่ยอมปรับเป็น :timestamptz เป็นค่าเริ่มต้น

ดังนั้นเราจะมาปรับค่าตรงนี้กัน ซึ่งที่มาก็มาจากใน rdoc ของ activerecord ส่วนของ postgresql นั่นเอง

โดยเพิ่ม ข้อมูลต่อไปนี้ ลงใน initializer

ActiveRecord::Base.time_zone_aware_types << :timestamptzActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type = :timestamptz

โดยบรรทัดแรก เป็นการบอกให้ activerecord ทราบว่า :timestamptz เป็น timezone aware type ทำให้เวลาแสดง class จะได้เป็นActiveSupport::TimeWithZone

ส่วนอีกบรรทัดจะเป็นการบอกว่าให้ Datetime type ใช้ :timestamptz

ซึ่งถ้าในกรณีที่ยังไม่เคย migrate database มาก่อน ก็สามารถ รัน rails db:migrate ก็จะได้ timestamp with timezone ออกมา

Table "public.products"
Column | Type | Collation | Nullable | Default
-------------+-----------------------------+-----------+----------+--------------------------------------
id | bigint | | not null | nextval('products_id_seq'::regclass)
test | timestamp(6) with time zone | | |
created_at | timestamp(6) with time zone | | not null |
updated_at | timestamp(6) with time zone | | not null |
part_number | character varying | | |

แต่ถ้าเคยมี table อยู่แล้ว อาจจะยังไม่สามารถเปลี่ยนให้ได้ จาก db:migrate ต้องออกแรงด้วย alter table เองไปก่อนครับ

Reference:

--

--

Teerayut Hiruntaraporn
Teerayut Hiruntaraporn

No responses yet