It is possible to register multiple connections, for example:
Granite::Connections << Granite::Adapter::Mysql.new(name: "legacy_db", url: "LEGACY_DB_URL")Granite::Connections << Granite::Adapter::Pg.new(name: "new_db", url: "NEW_DB_URL")class Foo < Granite::Baseconnection legacy_db# model fieldsendclass Bar < Granite::Baseconnection new_db# model fieldsend
In this example, we defined two connections. One to a MySQL database named "legacy_db", and another to a PG database named "new_db". The connection name given in the model maps to the name of a registered connection.
NOTE: How you store/supply each connection's URL is up to you; Granite only cares that it gets registered via
Granite::Connections << adapter_object.
timestamps macro defines
updated_at field for you.
class Bar < Granite::Baseconnection mysql# Other fieldstimestampsend
Would be equivalent to:
class Bar < Granite::Baseconnection mysqlcolumn created_at : Time?column updated_at : Time?end
Each model is required to have a primary key defined. Use the
column macro with the
primary: true option to denote the primary key.
NOTE: Composite primary keys are not yet supported.
```crystal class Site < Granite::Base connection mysql
column id : Int64, primary: true column name : String end
`belongs_to` associations can also be used as a primary key in much the same way.```crystalclass ChatSettings < Granite::Baseconnection mysql# chat_id would be the primary keybelongs_to chat : Chat, primary: trueend
The name and type of the primary key can also be changed from the recommended
id : Int64.
class Site < Granite::Baseconnection mysqlcolumn custom_id : Int32, primary: truecolumn name : Stringend
Primary keys are defined as auto incrementing by default. For natural keys, you can set
auto: false option.
class Site < Granite::Baseconnection mysqlcolumn custom_id : Int32, primary: true, auto: falsecolumn name : Stringend
For databases that utilize UUIDs as the primary key, the type of the primary key can be set to
UUID. This will generate a secure UUID when the model is saved.
class Book < Granite::Baseconnection mysqlcolumn isbn : UUID, primary: truecolumn name : Stringendbook = Book.newbook.name = "Moby Dick"book.isbn # => nilbook.savebook.isbn # => RFC4122 V4 UUID string
A default value can be defined that will be used if another value is not specified/supplied.
class Book < Granite::Baseconnection mysqlcolumn id : Int64, primary: truecolumn name : String = "DefaultBook"endbook = Book.newbook.name # => "DefaultBook"
By default, running
crystal docs will not include Granite methods, constants, and properties. To include these, use the
granite_docs flag when generating the documentation. E.x.
crystal docs -D granite_docs.
Doc block comments can be applied above the
# If the item is public.column published : Bool
Annotations can be a powerful method of adding property specific features with minimal amounts of code. Since Granite utilizes the
property keyword for its columns, annotations are able to be applied easily. These can either be
YAML::Field, or third party annotations.
class Foo < Granite::Baseconnection mysqltable fooscolumn id : Int64, primary: true@[JSON::Field(ignore: true)]@[Bar::Settings(other_option: 7)]column password : Stringcolumn name : Stringcolumn age : Int32end
Granite supports custom/special types via converters. Converters will convert the type into something the database can store when saving the model, and will convert the returned database value into that type on read.
Each converter has a
T generic argument that tells the converter what type should be read from the
DB::ResultSet. For example, if you wanted to use the
JSON converter and your underlying database column is
BLOB, you would use
Bytes, if it was
TEXT, you would use
Currently Granite supports various converters, each with their own supported database column types:
Enum(E, T) - Converts an Enum of type
E to/from a database column of type
T. Supported types for
Json(M, T) - Converters an
Object of type
M to/from a database column of type
T. Supported types for
M must implement
PgNumeric - Converts a
PG::Numeric value to a
Float64 on read.
The converter is defined on a per field basis. This example has an
OrderStatus enum typed field. When saved, the enum value would be converted to a string to be stored in the DB. Then, when read, the string would be used to parse a new instance of
enum OrderStatusActiveExpiredCompletedendclass Order < Granite::Baseconnection mysqltable foos# Other fieldscolumn status : OrderStatus, converter: Granite::Converters::Enum(OrderStatus, String)end