Skip to main content
Version: 0.5

Model fields

This page provides a reference for all the available field options and field types that can be used when defining models.

Common field options

The following field options can be used for all the available field types when declaring model fields using the field macro.

blank

The blank argument allows to define whether a field is allowed to receive blank values from a validation perspective. The fields with blank: false that receive blank values will make their associated model record validation fail. The default value for this argument is false.

db_column

The db_column argument can be used to specify the name of the column corresponding to the field at the database level. Unless specified, the database column name will correspond to the field name.

default

The default argument allows to define a default value for a given field. The default value for this argument is nil.

index

The index argument can be used to specify that a database index must be created for the corresponding column. The default value for this argument is false.

primary_key

The primary_key argument can be used to specify that a field corresponds to the primary key of the considered model table. The default value for this argument is false.

null

The null argument allows to define whether a field is allowed to store NULL values in the database. The default value for this argument is false.

unique

The unique argument allows to define that values for a specific field must be unique throughout the associated table. The default value for this argument is false.

Field types

big_int

A big_int field allows persisting 64-bit integers. In addition to the common field options, such fields support the following arguments:

auto

The auto argument auto-increment for the considered database column. Defaults to false.

This argument will be used mainly when defining integer IDs that automatically increment:

class MyModel < Marten::Model
field :id, :big_int, primary_key: true, auto: true
# ...
end

bool

A bool field allows persisting booleans.

date

A date field allows persisting date values, which map to Time objects in Crystal. In addition to the common field options, such fields support the following arguments:

auto_now

The auto_now argument allows ensuring that the corresponding field value is automatically set to the current time every time a record is saved. This provides a convenient way to define updated_at fields. Defaults to false.

auto_now_add

The auto_now_add argument allows ensuring that the corresponding field value is automatically set to the current time every time a record is created. This provides a convenient way to define created_at fields. Defaults to false.

date_time

A date_time field allows persisting date-time values, which map to Time objects in Crystal. In addition to the common field options, such fields support the following arguments:

auto_now

The auto_now argument allows ensuring that the corresponding field value is automatically set to the current time every time a record is saved. This provides a convenient way to define updated_at fields. Defaults to false.

auto_now_add

The auto_now_add argument allows ensuring that the corresponding field value is automatically set to the current time every time a record is created. This provides a convenient way to define created_at fields. Defaults to false.

duration

A duration field allows persisting duration values, which map to Time::Span objects in Crystal. duration fields are persisted as big integer values (number of nanoseconds) at the database level.

email

An email field allows to persist valid email addresses. In addition to the common field options, such fields support the following arguments:

max_size

The max_size argument is optional and defaults to 254 characters (in accordance with RFCs 3696 and 5321). It allows to specify the maximum size of the persisted email addresses. This maximum size is used for the corresponding column definition and when it comes to validating field values.

enum

An enum field allows persisting the value of an Enum. When defining enum fields, it's necessary to specify a values argument that matches the actual enum:

enum Category
NEWS
BLOG
end

class Article < Marten::Model
field :id, :big_int, primary_key: true, auto: true
field :category, :enum, values: Category
end

article = Article.last!
article.category # => Category::BLOG
info

The way enums are handled at the database level depends on the database backend being used. Indeed, an ENUM type is used for MySQL databases while column checks are used for SQLite and PostgreSQL databases.

In addition to the common field options, such fields support the following arguments:

values

The values argument is required and allows to specify the actual enum class that should be used for the field. It is worth mentioning that the configured enum will impact the values allowed for the corresponding column at the database level.

file

A file field allows persisting the reference to an uploaded file.

info

file fields can't be configured as primary keys.

storage

This optional argument can be used to configure the storage that will be used to persist the actual files. It defaults to the media files storage (configured via the media_files.storage setting), but can be overridden on a per-field basis if needed:

my_storage = Marten::Core::Storage::FileSystem.new(root: "files", base_url: "/files/")

class Attachment < Marten::Model
field :id, :big_int, primary_key: true, auto: true
field :uploaded_file, :file, storage: my_storage
end

Please refer to Managing files for more details on how to manage uploaded files and the associated storages.

upload_to

This optional argument can be used to configure where the uploaded files are persisted in the storage. It defaults to an empty string and can be set to either a string or a proc.

If set to a string, it allows to define in which directory of the underlying storage files will be persisted:

class Attachment < Marten::Model
field :id, :big_int, primary_key: true, auto: true
field :uploaded_file, :file, upload_to: "foo/bar"
end

If set to a proc, it allows to customize the logic allowing to generate the resulting path and filename:

class Attachment < Marten::Model
field :id, :big_int, primary_key: true, auto: true
field :uploaded_file, :file, upload_to: ->(filename : String) { File.join("files/uploads", filename) }
end

float

A float field allows persisting floating point numbers (Float64 objects).

int

An int field allows persisting 32-bit integers. In addition to the common field options, such fields support the following arguments:

auto

The auto argument auto-increment for the considered database column. Defaults to false.

This argument will be used mainly when defining integer IDs that automatically increment:

class MyModel < Marten::Model
field :id, :int, primary_key: true, auto: true
# ...
end

json

A json field allows persisting JSON values to the database.

JSON values are automatically parsed from the underlying database column and exposed as a JSON::Any object (or nil if no values are available) by default in Crystal:

class MyModel < Marten::Model
# Other fields...
field :metadata, :json
end

MyModel.last!.metadata # => JSON::Any object

Additionally, it is also possible to specify a serializable option in order to specify a class that makes use of JSON::Serializable. When doing so, the parsing of the JSON values will result in the initialization of the corresponding serializable objects:

class MySerializable
include JSON::Serializable

property a : Int32 | Nil
property b : String | Nil
end

class MyModel < Marten::Model
# Other fields...
field :metadata, :json, serializable: MySerializable
end

MyModel.last!.metadata # => MySerializable object
info

It should be noted that json fields are mapped to:

  • jsonb columns in PostgreSQL databases
  • text columns in MySQL databases
  • text columns in SQLite databases

serializable

The serializable arguments allows to specify that a class making use of JSON::Serializable should be used in order to parse the JSON values for the model field at hand. When specifying a serializable class, the values returned for the considered model fields will be instances of that class instead of JSON::Any objects.

slug

A slug field allows to persist valid slug values (ie. strings that can only include characters, numbers, dashes, and underscores). In addition to the common field options, such fields support the following arguments:

max_size

The max_size argument is optional and defaults to 50 characters. It allows to specify the maximum size of the persisted email addresses. This maximum size is used for the corresponding column definition and when it comes to validate field values.

info

As slug fields are usually used to query records, they are indexed by default. You can use the index option (index: false) to disable auto-indexing.

string

A string field allows to persist small or medium string values. In addition to the common field options, such fields support the following arguments:

max_size

The max_size argument is required and allows to specify the maximum size of the persisted string. This maximum size is used for the corresponding column definition and when it comes to validate field values.

min_size

The min_size argument allows defining the minimum size allowed for the persisted string. The default value for this argument is nil, which means that the minimum size is not validated by default.

text

A text field allows to persist large text values. In addition to the common field options, such fields support the following arguments:

max_size

The max_size argument allows to specify the maximum size of the persisted string. This maximum size is used when it comes to validate field values. Defaults to nil.

url

A url field allows persisting valid URL addresses. In addition to the common field options, such fields support the following arguments:

max_size

The max_size argument is optional and defaults to 200 characters. It allows to specify the maximum size of the persisted URLs. This maximum size is used for the corresponding column definition and when it comes to validate field values.

uuid

A uuid field allows persisting Universally Unique IDentifiers (UUID objects).

Relationship field types

many_to_many

A many_to_many field allows to define a many-to-many relationship. This special field type requires the use of a special to argument in order to specify the model class to which the current model is related.

For example, an Article model could have a many-to-many field towards a Tag model. In such case, an Article record could have many associated Tag records, and every Tag records could be associated to many Article records as well:

class Tag < Marten::Model
# ...
end

class Article < Marten::Model
# ...
field :tags, :many_to_many, to: Tag
end

In addition to the common field options, such fields support the following arguments:

to

The to argument is required and allows to specify the model class that is related to the model where the many_to_many field is defined.

The related argument allows defining the name of the reverse (or backward) relation on the targetted model. If we consider the previous example, it could be possible to define an articles backward relation in order to let Tag records expose their related Article records:

class Tag < Marten::Model
# ...
end

class Article < Marten::Model
# ...
field :tags, :many_to_many, to: Tag, related: :articles
end

When the related argument is used, a method will be automatically created on the targetted model by using the chosen argument's value. For example, this means that all the Article records using a specific Tag record could be accessed through the use of the Tag#articles method in the previous snippet.

The default value is nil, which means that no reverse relation is defined on the targetted model by default.

many_to_one

A many_to_one field allows defining a many-to-one relationship. This special field type requires the use of a special to argument in order to specify the model class to which the current model is related.

For example, an Article model could have a many-to-one field towards an Author model. In such case, an Article record would only have one associated Author record, but every Author record could be associated to many Article records:

class Author < Marten::Model
# ...
end

class Article < Marten::Model
# ...
field :author, :many_to_one, to: Author
end

In addition to the common field options, such fields support the following arguments:

to

The to argument is required and allows to specify the model class that is related to the model where the many_to_one field is defined.

The related argument allows defining the name of the reverse (or backward) relation on the targetted model. If we consider the previous example, it could be possible to define an articles backward relation in order to let Author records expose their related Article records:

class Author < Marten::Model
# ...
end

class Article < Marten::Model
# ...
field :author, :many_to_one, to: Author, related: :articles
end

When the related argument is used, a method will be automatically created on the targetted model by using the chosen argument's value. For example, this means that all the Article records associated with a specific Author record could be accessed through the use of the Author#articles method in the previous snippet.

The default value is nil, which means that no reverse relation is defined on the targetted model by default.

on_delete

The on_delete argument allows to specify the deletion strategy to adopt when a related record (one that is targeted by the many_to_one field) is deleted. The following strategies can be specified (as symbols):

  • :do_nothing: is the default strategy. With this strategy, Marten won't do anything to ensure that records referencing the record being deleted are deleted or updated. If the database enforces referential integrity (which will be the case for foreign key fields), this means that deleting a record could result in database errors.
  • :cascade: this strategy can be used to perform cascade deletions. When deleting a record, Marten will try to first destroy the other records that reference the object being deleted.
  • :protect: this strategy allows to explicitly prevent the deletion of records if they are referenced by other records. This means that attempting to delete a "protected" record will result in a Marten::DB::Errors::ProtectedRecord error.
  • :set_null: this strategy will set the reference column to null when the related record is deleted.

one_to_one

A one_to_one field allows defining a one-to-one relationship. This special field type requires the use of a special to argument in order to specify the model class to which the current model is related.

For example, a User model could have a one-to-one field towards a Profile model. In such case, the User model could only have one associated Profile record, and the reverse would be true as well (a Profile record could only have one associated User record). In fact, a one-to-one field is really similar to a many-to-one field, but with an additional unicity constraint:

class Profile < Marten::Model
# ...
end

class User < Marten::Model
# ...
field :profile, :one_to_one, to: Profile
end

In addition to the common field options, such fields support the following arguments:

to

The to argument is required and allows to specify the model class that is related to the model where the one_to_one field is defined.

The related argument allows defining the name of the reverse (or backward) relation on the targetted model. If we consider the previous example, it could be possible to define a user backward relation in order to let Profile records expose their related User record:

class Profile < Marten::Model
# ...
end

class User < Marten::Model
# ...
field :profile, :one_to_one, to: Profile, related: :user
end

When the related argument is used, a method will be automatically created on the targetted model by using the chosen argument's value. For example, this means that the User record associated with a specific Profile record could be accessed through the use of the Profile#user method in the previous snippet.

The default value is nil, which means that no reverse relation is defined on the targetted model by default.

on_delete

Same as the similar option for the #many_to_one field.