Railsでデフォルト生成されたIDカラムの上限値
対象読者
・RailsのIDカラムの上限値を知りたい人
・モデルの型定義について知りたい人
結論(デフォルト生成されたIDカラムの上限値)
※ PostgreSQLを使用する場合
-
上限値
- Rails5.1未満:4バイトの 2147483647
- Rails5.1以降:8バイトの 9223372036854775807
-
参考情報
Rails5.1未満で作成済みのマイグレーションファイルで作成したテーブル
# マイグレーションファイルの継承元が[5.1]未満
class **** < ActiveRecord::Migration[5.0]
idは serial型 で定義される為、4バイトの 2147483648 以上 の値を設定し、保存するときにエラー発生
Rails5.1以降で作成済みのマイグレーションファイルで作成したテーブル
# マイグレーションファイルの継承元が[5.1]以降
class **** < ActiveRecord::Migration[5.1]
idは bigserial型 で定義される為、8バイトの 9223372036854775808 以上 の値を設定し、保存するときにエラー発生
実験
上限値を入力してエラーを発生させてみる
serial型 の場合
# 2147483647 だとOK
pry(main)> Author.new(id: 2147483647).save
(0.3ms) BEGIN
Author Create (0.5ms) INSERT INTO "authors" ("id", "created_at", "updated_at") VALUES ($1, $2, $3) [["id", 2147483647], ["created_at", "2021-07-16 10:36:18.537225"], ["updated_at", "2021-07-16 10:36:18.537225"]]
SQL (0.2ms) SELECT currval('public.authors_id_seq')
(0.5ms) COMMIT
’=> true
# 4バイトの 2147483648 でエラー発生
pry(main)> Author.new(id: 2147483648).save
(0.2ms) BEGIN
(0.2ms) ROLLBACK
ActiveModel::RangeError: 2147483648 is out of range for ActiveModel::Type::Integer with limit 4 bytes
from **********/vendor/bundle/ruby/2.6.0/gems/activemodel-5.2.4.3/lib/active_model/type/integer.rb:53:in `ensure_in_range'
# SELECT setval('authors_id_seq', 2147483647);
# シーケンスを上限値に設定して保存するとエラー発生
pry(main)> Author.new(creator_id: 0, updater_id: 0).save
(16.0ms) BEGIN
Author Create (33.4ms) INSERT INTO "authors" ("created_at", "updated_at") VALUES ($1, $2) [["created_at", "2021-07-16 13:05:52.178741"], ["updated_at", "2021-07-16 13:05:52.178741"]]
(6.1ms) ROLLBACK
ActiveRecord::StatementInvalid: PG::DataException: ERROR: nextval: reached maximum value of sequence "authors_id_seq" (2147483647)
: INSERT INTO "authors" ("created_at", "updated_at", "creator_id", "updater_id") VALUES ($1, $2)
from **********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.3/lib/active_record/connection_adapters/postgresql_adapter.rb:611:in `async_exec'
Caused by PG::DataException: ERROR: nextval: reached maximum value of sequence "authors_id_seq" (2147483647)
bigserial型 の場合
# 8バイトの 9223372036854775808 でエラー発生
[1] pry(main)> Book.new(id: 9223372036854775808, name: 'hoge').save
(0.1ms) BEGIN
(0.1ms) ROLLBACK
ActiveModel::RangeError: 9223372036854775808 is out of range for ActiveModel::Type::Integer with limit 8 bytes
from **********/vendor/bundle/ruby/2.6.0/gems/activemodel-5.2.4.4/lib/active_model/type/integer.rb:53:in `ensure_in_range'
その他の調査ログ
それっぽいところで caller
メソッドを実行して、呼び元を確認してみる
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql_adapter.rb:452:in `get_oid_type'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/schema_statements.rb:668:in `fetch_type_metadata'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/schema_statements.rb:649:in `new_column_from_field'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/schema_statements.rb:114:in `block in columns'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/schema_statements.rb:113:in `map'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/schema_statements.rb:113:in `columns'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/schema_cache.rb:69:in `columns'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/schema_cache.rb:75:in `columns_hash'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/model_schema.rb:466:in `load_schema!'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/attributes.rb:234:in `load_schema!'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/attribute_decorators.rb:51:in `load_schema!'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/model_schema.rb:459:in `block in load_schema'",
"*********/.rbenv/versions/2.6.6/lib/ruby/2.6.0/monitor.rb:235:in `mon_synchronize'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/model_schema.rb:456:in `load_schema'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/model_schema.rb:346:in `attribute_types'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/attribute_methods.rb:230:in `has_attribute?'",
"*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/inheritance.rb:55:in `new'",
"*********/app/controllers/books_controller.rb:9:in `create'",
get_oid_type
を見てみると、、
def get_oid_type(oid, fmod, column_name, sql_type = "".freeze)
if !type_map.key?(oid)
load_additional_types([oid])
end
type_map.fetch(oid, fmod, sql_type) {
warn "unknown OID #{oid}: failed to recognize type of '#{column_name}'. It will be treated as String."
Type.default_value.tap do |cast_type|
type_map.register_type(oid, cast_type)
end
}
end
type_map
をfetch
すると型を取得できるぽい
bigserial
の場合 ↓↓↓
[8] pry(#<ActiveRecord::ConnectionAdapters::PostgreSQLAdapter>)> type_map.fetch(oid, fmod, sql_type)
=> #<ActiveModel::Type::Integer:0x00007fdb07db2650 @limit=8, @precision=nil, @range=-9223372036854775808...9223372036854775808, @scale=nil>
[9] pry(#<ActiveRecord::ConnectionAdapters::PostgreSQLAdapter>)> oid
=> 20
[10] pry(#<ActiveRecord::ConnectionAdapters::PostgreSQLAdapter>)> fmod
=> -1
[11] pry(#<ActiveRecord::ConnectionAdapters::PostgreSQLAdapter>)> sql_type
=> "bigint"
いつの間にか取得されているbigint
やoid
などの情報はcolumn_definitions
で取得するぽい
def column_definitions(table_name)
query(<<-end_sql, "SCHEMA")
SELECT a.attname, format_type(a.atttypid, a.atttypmod),
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
c.collname, col_description(a.attrelid, a.attnum) AS comment
FROM pg_attribute a
LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
LEFT JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
WHERE a.attrelid = #{quote(quote_table_name(table_name))}::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
end_sql
end
テーブルカラムの定義情報の取得
SQLクライアントで実行してみると、、、
SELECT a.attname, format_type(a.atttypid, a.atttypmod),
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
c.collname, col_description(a.attrelid, a.attnum) AS comment
FROM pg_attribute a
LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
LEFT JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
WHERE a.attrelid = 'books'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
-- 以下のような結果がテーブル定義を取得できる
attname |format_type |pg_get_expr |attnotnull|atttypid|atttypmod|collname|comment|
----------+---------------------------+---------------------------------+----------+--------+---------+--------+-------+
id |bigint |nextval('books_id_seq'::regclass)|true | 20| -1| | |
name |character varying | |false | 1043| -1| | |
created_at|timestamp without time zone| |true | 1114| -1| | |
updated_at|timestamp without time zone| |true | 1114| -1| | |
モデルの型決定に使用する変換用のマッピング情報
type_map
はDB接続時に作成されるぽい
# 48行目 postgresql_connection
ConnectionAdapters::PostgreSQLAdapter.new(nil, logger, conn_params, config)
# 234行目 initialize
@type_map = Type::HashLookupTypeMap.new
initialize_type_map
# 460行目 initialize_type_map
def initialize_type_map(m = type_map)
m.register_type "int2", Type::Integer.new(limit: 2)
m.register_type "int4", Type::Integer.new(limit: 4)
m.register_type "int8", Type::Integer.new(limit: 8)
m.register_type "oid", OID::Oid.new
# ...省略
type_map
にはこんなの↓↓↓が入っていて、oid
をキーにProc
を取得している
長すぎる type_map の内容をクリックして展開
[6] pry(#<ActiveRecord::ConnectionAdapters::PostgreSQLAdapter>)> type_map
=> #<ActiveRecord::Type::HashLookupTypeMap:0x00007fdb07db2a10
@cache=#<Concurrent::Map:0x00007fdb07db29c0 entries=4 default_proc=#<Proc:0x00007fdb07db2920@/*************/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:10>>,
@mapping=
{"int2"=>#<Proc:0x00007fdb07db27e0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"int4"=>#<Proc:0x00007fdb07db26a0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"int8"=>#<Proc:0x00007fdb07db2498@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"oid"=>#<Proc:0x00007fdb07db23d0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"float4"=>#<Proc:0x00007fdb07db2358@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"float8"=>#<Proc:0x00007fdb07db2308@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
"text"=>#<Proc:0x00007fdb07db2290@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"varchar"=>#<Proc:0x00007fdb07db2240@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract_adapter.rb:530>,
"char"=>#<Proc:0x00007fdb07db21f0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
"name"=>#<Proc:0x00007fdb07db21a0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
"bpchar"=>#<Proc:0x00007fdb07db2150@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
"bool"=>#<Proc:0x00007fdb07db20d8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"bit"=>#<Proc:0x00007fdb07db2088@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract_adapter.rb:530>,
"varbit"=>#<Proc:0x00007fdb07db2038@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract_adapter.rb:530>,
"timestamptz"=>#<Proc:0x00007fdb07db1fe8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
"date"=>#<Proc:0x00007fdb07db1f70@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"money"=>#<Proc:0x00007fdb07db1ef8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"bytea"=>#<Proc:0x00007fdb07db1e80@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"point"=>#<Proc:0x00007fdb07db1e08@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"hstore"=>#<Proc:0x00007fdb07db1d90@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"json"=>#<Proc:0x00007fdb07db1d18@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"jsonb"=>#<Proc:0x00007fdb07db1ca0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"cidr"=>#<Proc:0x00007fdb07db1c28@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"inet"=>#<Proc:0x00007fdb07db1bb0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"uuid"=>#<Proc:0x00007fdb07db1b38@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"xml"=>#<Proc:0x00007fdb07db1ac0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"tsvector"=>#<Proc:0x00007fdb07db1a20@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"macaddr"=>#<Proc:0x00007fdb07db1980@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"citext"=>#<Proc:0x00007fdb07db18e0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"ltree"=>#<Proc:0x00007fdb07db1840@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"line"=>#<Proc:0x00007fdb07db17a0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"lseg"=>#<Proc:0x00007fdb07db1700@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"box"=>#<Proc:0x00007fdb07db1660@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"path"=>#<Proc:0x00007fdb07db15c0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"polygon"=>#<Proc:0x00007fdb07db1520@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"circle"=>#<Proc:0x00007fdb07db1480@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
"interval"=>#<Proc:0x00007fdb07db1430@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql_adapter.rb:499>,
"time"=>#<Proc:0x00007fdb07db13e0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract_adapter.rb:537>,
"timestamp"=>#<Proc:0x00007fdb07db1390@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract_adapter.rb:537>,
"numeric"=>#<Proc:0x00007fdb07db1368@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql_adapter.rb:507>,
16=>#<Proc:0x00007fdb0be6dac8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
17=>#<Proc:0x00007fdb0be6da78@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
18=>#<Proc:0x00007fdb0be6da28@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
19=>#<Proc:0x00007fdb0be6d9d8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
20=>#<Proc:0x00007fdb0be6d988@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
21=>#<Proc:0x00007fdb0be6d938@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
23=>#<Proc:0x00007fdb0be6d8e8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
25=>#<Proc:0x00007fdb0be6d898@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
26=>#<Proc:0x00007fdb0be6d848@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
114=>#<Proc:0x00007fdb0be6d7f8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
142=>#<Proc:0x00007fdb0be6d7a8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
600=>#<Proc:0x00007fdb0be6d758@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
601=>#<Proc:0x00007fdb0be6d708@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
602=>#<Proc:0x00007fdb0be6d6b8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
603=>#<Proc:0x00007fdb0be6d668@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
604=>#<Proc:0x00007fdb0be6d618@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
628=>#<Proc:0x00007fdb0be6d5c8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
700=>#<Proc:0x00007fdb0be6d578@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
701=>#<Proc:0x00007fdb0be6d528@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
718=>#<Proc:0x00007fdb0be6d4d8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
790=>#<Proc:0x00007fdb0be6d488@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
829=>#<Proc:0x00007fdb0be6d438@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
869=>#<Proc:0x00007fdb0be6d3e8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
650=>#<Proc:0x00007fdb0be6d398@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
1042=>#<Proc:0x00007fdb0be6d348@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
1043=>#<Proc:0x00007fdb0be6d2f8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
1082=>#<Proc:0x00007fdb0be6d2a8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
1083=>#<Proc:0x00007fdb0be6d258@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
1114=>#<Proc:0x00007fdb0be6d208@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
1184=>#<Proc:0x00007fdb0be6d1b8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
1186=>#<Proc:0x00007fdb0be6d168@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
1560=>#<Proc:0x00007fdb0be6d118@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
1562=>#<Proc:0x00007fdb0be6d0c8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
1700=>#<Proc:0x00007fdb0be6d078@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
2950=>#<Proc:0x00007fdb0be6d028@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
3614=>#<Proc:0x00007fdb0be6cfd8@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
3802=>#<Proc:0x00007fdb0be6cf88@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/hash_lookup_type_map.rb:7>,
13136=>#<Proc:0x00007fdb0be6cc90@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
13139=>#<Proc:0x00007fdb0be6c8d0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
13141=>#<Proc:0x00007fdb0be6c510@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
13146=>#<Proc:0x00007fdb0be77fa0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
13148=>#<Proc:0x00007fdb0be77be0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
143=>#<Proc:0x00007fdb0be77b40@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
199=>#<Proc:0x00007fdb0be77aa0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
629=>#<Proc:0x00007fdb0be77a00@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
719=>#<Proc:0x00007fdb0be77960@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
791=>#<Proc:0x00007fdb0be778c0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1000=>#<Proc:0x00007fdb0be77820@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1001=>#<Proc:0x00007fdb0be77780@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1002=>#<Proc:0x00007fdb0be776e0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1003=>#<Proc:0x00007fdb0be77640@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1005=>#<Proc:0x00007fdb0be775a0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1007=>#<Proc:0x00007fdb0be77500@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1009=>#<Proc:0x00007fdb0be77460@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1028=>#<Proc:0x00007fdb0be773c0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1014=>#<Proc:0x00007fdb0be77320@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1015=>#<Proc:0x00007fdb0be77280@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1016=>#<Proc:0x00007fdb0be771e0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1017=>#<Proc:0x00007fdb0be77140@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1018=>#<Proc:0x00007fdb0be770a0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1019=>#<Proc:0x00007fdb0be77000@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1020=>#<Proc:0x00007fdb0be76f60@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1021=>#<Proc:0x00007fdb0be76ec0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1022=>#<Proc:0x00007fdb0be76e20@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1027=>#<Proc:0x00007fdb0be76d80@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1040=>#<Proc:0x00007fdb0be76ce0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1041=>#<Proc:0x00007fdb0be76c40@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
651=>#<Proc:0x00007fdb0be76ba0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1115=>#<Proc:0x00007fdb0be76b00@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1182=>#<Proc:0x00007fdb0be76a60@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1183=>#<Proc:0x00007fdb0be769c0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1185=>#<Proc:0x00007fdb0be76920@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1187=>#<Proc:0x00007fdb0be76880@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1231=>#<Proc:0x00007fdb0be767e0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1561=>#<Proc:0x00007fdb0be76740@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
1563=>#<Proc:0x00007fdb0be766a0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
2951=>#<Proc:0x00007fdb0be76600@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
3643=>#<Proc:0x00007fdb0be76560@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
3807=>#<Proc:0x00007fdb0be764c0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
13135=>#<Proc:0x00007fdb0be76420@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
13138=>#<Proc:0x00007fdb0be76380@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
13140=>#<Proc:0x00007fdb0be762e0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
13145=>#<Proc:0x00007fdb0be76240@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
13147=>#<Proc:0x00007fdb0be761a0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
3904=>#<Proc:0x00007fdb0be76100@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
3906=>#<Proc:0x00007fdb0be76060@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
3908=>#<Proc:0x00007fdb0be75fc0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
3910=>#<Proc:0x00007fdb0be75f20@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
3912=>#<Proc:0x00007fdb0be75e80@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
3926=>#<Proc:0x00007fdb0be75de0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb:97>,
22=>#<Proc:0x00007fdb0be75ac0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>,
30=>#<Proc:0x00007fdb0be757a0@/*********/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.4.4/lib/active_record/type/type_map.rb:32>}>
モデルの型定義
モデルの型はテーブル定義情報を基に設定される
https://github.com/rails/rails/blob/main/activerecord/lib/active_record/base.rb
Active Record objects don't specify their attributes directly, but rather infer them from the table definition with which they're linked. Adding, removing, and changing attributes and their type is done directly in the database. Any change is instantly reflected in the Active Record objects. The mapping that binds a given Active Record class to a certain database table will happen automatically in most common cases, but can be overwritten for the uncommon ones.
type_map
に設定されている Type::Integer.new(limit: 8)
のように、limit
を引数にして、Integerクラス
のインスタンスが作成される。
上限値を超えてエラーが発生するときは、このクラスで値が範囲外かどうかのチェックをしている。
def initialize(*)
super
@range = min_value...max_value
end
# 継承元のコード抜粋:activemodel-5.2.4.4/lib/active_model/type/value.rb
# initialize_type_map メソッドの Type::Integer.new(limit: 8) で呼び出されるぽい
def initialize(precision: nil, limit: nil, scale: nil)
@precision = precision
@scale = scale
@limit = limit
end
# @rangeの範囲内かを確認している
def ensure_in_range(value)
unless range.cover?(value)
raise ActiveModel::RangeError, "#{value} is out of range for #{self.class} with limit #{_limit} bytes"
end
end
モデルの型はテーブル定義情報を基に設定される為、
以下のように直接テーブル定義情報を変更すると、モデルの型も変更される。
ALTER TABLE public.books ALTER COLUMN id TYPE bigint USING id::bigint;
Discussion