Branch: master
Find file Copy path
c441e5f Jan 7, 2019
1 contributor

Users who have contributed to this file

176 lines (121 sloc) 4.81 KB

Getting Started


Add this library to your projects dependencies along with the driver in your shard.yml. This can be used with any framework but was originally designed to work with the amber framework in mind. This library will work with Kemal or any other framework as well.

    github: amberframework/granite

  # Pick your database
    github: crystal-lang/crystal-mysql

    github: crystal-lang/crystal-sqlite3

    github: will/crystal-pg

Next you will need to register an adapter. This should be one of the first things in your main Crystal file, before Granite is required.

Granite::Adapters <<{name: "mysql", url: "YOUR_DATABASE_URL"})

# Rest of code...

Supported adapters include Mysql, Pg, and Sqlite.



Here is an example using Granite Model

require "granite/adapter/mysql"

class Post < Granite::Base
  adapter mysql
  field name : String
  field body : String

This model is using an adapter named mysql, registered in the example above. It is possible to register multiple adapters with different names/URLs, for example:

Granite::Adapters <<{name: "LegacyDB", url: "LEGACY_DB_URL"})
Granite::Adapters <<{name: "NewDb", url: "NEW_DB_URL"})

class Foo < Granite::Base
  adapter LegacyDB
  # model fields

class Bar < Granite::Base
  adapter NewDb
  # model fields

In this example, model Foo, is connecting to a MySQL DB at the URL of LEGACY_DB_URL while model Bar is connecting to a Postgres DB at the URL NEW_DB_URL. The adapter name given in the model maps to the name of a registered adapter.

NOTE: How you store/supply each adapter's URL is up to you; Granite only cares that it gets registered via Granite::Adapters << adapter_object.

id, created_at, updated_at

The primary key is automatically created for you and if you use timestamps they will be automatically updated for you.

Here are the MySQL field definitions for id, created_at, updated_at

  # Your fields go here
  created_at TIMESTAMP
  updated_at TIMESTAMP

Custom Primary Key

For legacy database mappings, you may already have a table and the primary key is not named id or Int64.

Use the primary macro to define your own primary key

class Site < Granite::Base
  adapter mysql
  primary custom_id : Int32
  field name : String

This will override the default primary key of id : Int64.

Natural Keys

For natural keys, you can set auto: false option to disable auto increment.

class Site < Granite::Base
  adapter mysql
  primary code : String, auto: false
  field name : String


For databases that utilize UUIDs as the primary key, the primary macro can be used as a String type, with the auto: :uuid option. This will generate a secure UUID when the model is saved.

class Book < Granite::Base
  adapter mysql
  primary isbn : String, auto: :uuid
  field name : String

book = = "Moby Dick"
book.isbn # => nil
book.isbn # => RFC4122 V4 UUID string

Default values

A default value can be assigned to a field that will be used if another value is not specified/supplies.

class Book < Granite::Base
  adapter mysql
  field name : String, default: "DefaultBook"

book = # => "DefaultBook"

Generating Documentation

By default, running crystal docs will not include Granite methods, constants, and properties. To include these, have an ENV variable: DISABLE_GRANITE_DOCS=false set before running crystal docs.

The field and primary macros have a comment option that will specify the documentation comment to apply to that property's getter and setter.

field age : Int32, comment: "# Number of seconds since the post was posted"

Third-Party Annotations

Annotations can be a powerful method of adding property specific features with minimal amounts of code. Since Granite utilizes the property keyword for its fields, annotations are able to be applied easily. This is accomplished by using the annotations option on a field, similar to the comment option above. It is used in the form of annotations: ["annotation1", "annotation2"], for example:

class Foo < Granite::Base
  adapter mysql
  table_name foos

  field name : String
  field password : String, annotations: ["@[Foo::Options(option1: true)]", "@[Bar::Settings(other_option: 7)]"]
  field age : Int32

Notice the values of the array are exactly as what you would put on a normal property, just as strings. In this case, Granite will apply the two annotations to the password property only.