ワンクリックで
grant-models-and-columns
Defining Grant ORM models with columns, types, primary keys, timestamps, connections, converters, and serialization.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Defining Grant ORM models with columns, types, primary keys, timestamps, connections, converters, and serialization.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Grant ORM advanced features including enum attributes, dirty tracking, serialized columns, value objects, horizontal sharding, and async operations.
Grant ORM associations including belongs_to, has_one, has_many, has_many through, polymorphic, dependent options, counter_cache, eager loading, and nested attributes.
Grant ORM lifecycle callbacks, transaction blocks, nested transactions with savepoints, isolation levels, optimistic and pessimistic locking.
Create, read, update, and delete operations in Grant ORM including bulk operations, batch processing, upserts, and convenience methods.
Generate a new Grant ORM model file with proper structure, column definitions, validations, associations, and callbacks.
Grant ORM query builder API including where clauses, operators, WhereChain, OR/NOT groups, scopes, aggregations, raw SQL, and Enumerable integration.
| name | grant-models-and-columns |
| description | Defining Grant ORM models with columns, types, primary keys, timestamps, connections, converters, and serialization. |
| user-invocable | false |
All Grant models inherit from Grant::Base and use macros to define their schema:
class User < Grant::Base
connection pg # Database connection to use
table users # Table name (optional, defaults to pluralized class name)
column id : Int64, primary: true
column name : String
column email : String
timestamps # Adds created_at and updated_at as Time?
end
Grant::Baseconnection macro specifies which database adapter to use (maps to a registered connection name)table macro maps to a database table (optional -- inferred from class name if omitted)column macro defines the schema and data typescolumn column_name : ColumnType, options
| Option | Description | Example |
|---|---|---|
primary: true | Marks as primary key | column id : Int64, primary: true |
auto: false | Disables auto-increment | column uuid : String, primary: true, auto: false |
converter: | Custom type converter | column data : JSON::Any, converter: Grant::Converters::Json |
nil: false | Makes column required | column name : String, nil: false |
| Default value | Crystal expression after = | column active : Bool = true |
class Product < Grant::Base
connection pg
# Integer types
column id : Int64, primary: true # BIGINT
column quantity : Int32 # INTEGER
column position : Int16 # SMALLINT
column status_code : Int8 # TINYINT
# Floating point
column price : Float64 # DOUBLE PRECISION
column rating : Float32 # FLOAT
# String types
column name : String # VARCHAR/TEXT
column description : String? # Nullable string
# Boolean
column active : Bool = true # BOOLEAN
column featured : Bool = false
# Time/Date
column published_at : Time? # TIMESTAMP
column expires_on : Time?
timestamps # created_at, updated_at as Time?
end
class AdvancedModel < Grant::Base
connection pg
# UUID (PostgreSQL, MySQL 8+)
column id : UUID, primary: true
# JSON (PostgreSQL JSONB, MySQL JSON, SQLite TEXT)
column metadata : JSON::Any?
column settings : JSON::Any = JSON.parse("{}")
# Arrays (PostgreSQL only)
column tags : Array(String)?
column scores : Array(Int32)?
column prices : Array(Float64)?
# Binary data
column file_data : Bytes?
end
column id : Int64, primary: true
column custom_id : Int32, primary: true
column iso_code : String, primary: true, auto: false
Automatically generates a secure UUID on save:
class Document < Grant::Base
connection pg
column id : UUID, primary: true
column title : String
end
doc = Document.new(title: "Report")
doc.id # => nil
doc.save
doc.id # => "550e8400-e29b-41d4-a716-446655440000"
class OrderItem < Grant::Base
connection pg
table order_items
column order_id : Int64, primary: true
column product_id : Int64, primary: true
column quantity : Int32
composite_primary_key [:order_id, :product_id]
end
class ChatSettings < Grant::Base
connection mysql
belongs_to chat : Chat, primary: true
end
column status : String = "draft"
column views : Int32 = 0
column featured : Bool = false
column tags : Array(String) = [] of String
class Token < Grant::Base
connection pg
column id : Int64, primary: true
column value : String?
column expires_at : Time?
before_create :set_defaults
private def set_defaults
self.value ||= Random::Secure.hex(32)
self.expires_at ||= 24.hours.from_now
end
end
The timestamps macro adds created_at : Time? and updated_at : Time?:
class Bar < Grant::Base
connection mysql
column id : Int64, primary: true
timestamps
end
This is equivalent to explicitly defining:
column created_at : Time?
column updated_at : Time?
Grant::Connections << Grant::Adapter::Pg.new(
name: "primary",
url: ENV["PRIMARY_DATABASE_URL"]
)
Grant::Connections << Grant::Adapter::Mysql.new(
name: "legacy",
url: ENV["LEGACY_DATABASE_URL"]
)
Grant::Connections << Grant::Adapter::Sqlite.new(
name: "cache",
url: "sqlite3://./cache.db"
)
class User < Grant::Base
connection primary
# ...
end
class LegacyCustomer < Grant::Base
connection legacy
table customers
# ...
end
Grant supports custom types via converters that transform values to/from database-compatible formats.
Grant::Converters::Enum(E, T) -- Converts Crystal enum E to/from database type T (Number, String, or Bytes)Grant::Converters::Json(M, T) -- Converts object M (must implement #to_json/.from_json) to/from T (String, JSON::Any, or Bytes)Grant::Converters::PgNumeric -- Converts PG::Numeric to Float64enum OrderStatus
Active
Expired
Completed
end
class Order < Grant::Base
connection mysql
column id : Int64, primary: true
column status : OrderStatus, converter: Grant::Converters::Enum(OrderStatus, String)
end
class Settings
include JSON::Serializable
property theme : String = "light"
property notifications : Bool = true
end
class User < Grant::Base
connection pg
column id : Int64, primary: true
column preferences : Settings, converter: Grant::Converters::Json(Settings, String)
end
module Grant::Converters
class EncryptedString < Grant::Converters::Base(String, String)
def self.from_db(value : String) : String
Base64.decode_string(value)
end
def self.to_db(value : String) : String
Base64.encode(value)
end
end
end
Grant includes JSON::Serializable and YAML::Serializable by default:
class ApiModel < Grant::Base
connection pg
column id : Int64, primary: true
@[JSON::Field(key: "user_name")]
column name : String
@[JSON::Field(ignore: true)]
column internal_notes : String?
end
model = ApiModel.find(1)
model.to_json # name serialized as "user_name", internal_notes excluded
Array(String), Array(Int32)), JSONB, UUID, full-text search scopesBy default, crystal docs does not include Grant methods. Use the flag:
crystal docs -D grant_docs