Ecto.Model.Schema

Parsed documentation:
View on GitHub
Defines a schema for a model.

A schema is a struct with associated metadata that is persisted to a
repository. Every schema model is also a struct, that means that you work
with models just like you would work with structs.

## Example

    defmodule User do
      use Ecto.Model.Schema

      schema "users" do
        field :name, :string
        field :age, :integer, default: 0
        has_many :posts, Post
      end
    end

## Types and casting

When defining the schema, types need to be given. Those types are specific
to Ecto and must be one of:

Ecto type               | Elixir type             | Literal syntax in query
:---------------------- | :---------------------- | :---------------------
`:integer`              | `integer`               | 1, 2, 3
`:float`                | `float`                 | 1.0, 2.0, 3.0
`:boolean`              | `boolean`               | true, false
`:string`               | UTF-8 encoded `binary`  | "hello"
`:binary`               | `binary`                | `<<int, int, int, ...>>`
`:uuid`                 | 16 byte `binary`        | `uuid(binary_or_string)`
`{:array, inner_type}`  | `list`                  | `[value, value, value, ...]`
`:decimal`              | [`Decimal`](https://github.com/ericmj/decimal)
`:datetime`             | `%Ecto.DateTime{}`
`:date`                 | `%Ecto.Date{}`
`:time`                 | `%Ecto.Time{}`

Models can also have virtual fields by passing the `virtual: true`
option. These fields are not persisted to the database and can
optionally not be type checked by declaring type `:any`.

When manipulating the struct, it is the responsibility of the
developer to ensure the fields are cast to the proper value. For
example, you can create a weather struct with an invalid value
for `temp_lo`:

    iex> weather = %Weather{temp_lo: "0"}
    iex> weather.temp_lo
    "0"

However, if you attempt to persist the struct above, an error will
be raised since Ecto validates the types when building the query.

## Schema defaults

When using the block syntax, the created model uses the default
of a primary key named `:id`, of type `:integer`. This can be
customized by passing `primary_key: false` to schema:

    schema "weather", primary_key: false do
      ...
    end

Or by passing a tuple in the format `{field, type, opts}`:

    schema "weather", primary_key: {:custom_field, :string, []} do
      ...
    end

Implicit defaults can be specified via the `@schema_defaults` attribute.
This is useful if you want to use a different default primary key
through your entire application.

The supported options are:

* `primary_key` - either `false`, or a `{field, type, opts}` tuple
* `foreign_key_type` - sets the type for any `belongs_to` associations.
  This can be overridden using the `:type` option to the `belongs_to`
  statement. Defaults to type `:integer`

## Example

    defmodule MyApp.Model do
      defmacro __using__(_) do
        quote do
          @schema_defaults primary_key: {:uuid, :string, []},
                           foreign_key_type: :string
          use Ecto.Model
        end
      end
    end

    defmodule MyApp.Post do
      use MyApp.Model
      schema "posts" do
        has_many :comments, MyApp.Comment
      end
    end

    defmodule MyApp.Comment do
      use MyApp.Model
      schema "comments" do
        belongs_to :post, MyApp.Comment
      end
    end

Any models using `MyApp.Model will get the `:uuid` field, with type
`:string` as the primary key.

The `belongs_to` association on `MyApp.Comment` will also now require
that `:post_id` be of `:string` type to reference the `:uuid` of a
`MyApp.Post` model.

## Reflection

Any schema module will generate the `__schema__` function that can be used for
runtime introspection of the schema.

* `__schema__(:source)` - Returns the source as given to `schema/2`;
* `__schema__(:primary_key)` - Returns the field that is the primary key or
                               `nil` if there is none;

* `__schema__(:fields)` - Returns a list of all non-virtual field names;
* `__schema__(:field, field)` - Returns the type of the given non-virtual field;

* `__schema__(:associations)` - Returns a list of all association field names;
* `__schema__(:association, assoc)` - Returns the association reflection of the given assoc;

* `__schema__(:load, values)` - Loads a new model struct from the given non-virtual
                                field values;

Furthermore, both `__struct__` and `__assign__` functions are defined
so structs and assignment functionalities are available.
No suggestions.
Please help! Open an issue on GitHub if this assessment is incorrect.