module Jennifer::Model::Mapping

Overview

Contains macros to define model mapping.

To define model mapping use .mapping macro. It accepts hash, tuple and splatted tuple, where keys are model attributes (they reflects column names but this can be overided) and values - mapping properties. Mapping value can be Class, HashLiteral, NamedTupleLiteral or constant that can be resolved as HashLiteral or NamedTupleLiteral.

Available mapping properties:

class Contact < Jennifer::Model::Base
  with_timestamps
  mapping(
    id: Primary32, # same as { type: Int32, primary: true }
    name: String,
    gender: {type: String?},
    age: {type: Int32, default: 10},
    description: String?,
    created_at: Time?,
    updated_at: Time | Nil
  )
end

Mapping type

Constants used as a :type value and presents subset of mapping properties are called mapping type. To use them you should firstly register it

class ApplicationRecord < Jennifer::Model::Base
  EmptyString = {
    type:    String,
    default: "",
  }

  {% TYPES << "EmptyString" %}
  # or if this is outside of model or view scope
  {% ::Jennifer::Macros::TYPES << "EmptyString" %}
end

For more details about exiting mapping types see Macros and Authentication.

Inheritance

Mapping also can be specified in abstract super class to be shared with all subclass models

class ApplicationRecord < Jennifer::Model::Base
  mapping(
    id: Primary32
  )
end

class User < ApplicationRecord
  mapping(
    name: String
  )
end

Or inside of a module

module SharedMapping
  include Jennifer::Model::Mapping

  mapping(
    id: Primary32
  )
end

class User < Jennifer::Model::Base
  include SharedMapping

  mapping(
    email: String
  )
end

.mapping can be used only once per module/class definition. If class has no field to be added after inheritance or module inclusion - place .mapping without any argument.

STI

For single table inheritance just define define parent non-abstract class with all common fields and type: String extra field and inherit from it. Any class inherited from non-abstract model automatically behaves in scope of "single table inheritance".

class Profile < Jennifer::Model::Base
  mapping(
    id: Primary32,
    login: String,
    contact_id: Int32?,
    type: String,
    virtual_parent_field: {type: String?, virtual: true}
  )
end

class FacebookProfile < Profile
  mapping(
    uid: String?, # for testing purposes
    virtual_child_field: {type: Int32?, virtual: true}
  )
end

Included Modules

Direct including types

Defined in:

jennifer/model/mapping.cr

Instance Method Summary

Macro Summary

Instance Method Detail

def attribute_metadata(name : String | Symbol) #

[View source]

Macro Detail

macro mapping(properties, strict = true) #

Defines model mapping.

Acceptable keys:

  • type
  • getter
  • setter
  • null
  • primary
  • virtual
  • default
  • converter
  • column

For more details see Mapping module documentation.


[View source]
macro mapping(**properties) #

Defines model mapping.

Acceptable keys:

  • type
  • getter
  • setter
  • null
  • primary
  • virtual
  • default
  • converter
  • column

For more details see Mapping module documentation.


[View source]