Skip to content

Instantly share code, notes, and snippets.

@pikender
Last active Apr 11, 2016
Embed
What would you like to do?
Ecto Model Schema Extension
## Library Code
## Defines DSL to be used by Service Code
## in order to get properly consumed by Consumer
defmodule Nectar.ModelExtension do
defmacro __using__(_opts) do
quote do
Module.register_attribute(__MODULE__, :schema_changes, accumulate: true)
import Nectar.ModelExtension, only: [add_to_schema: 1]
@before_compile Nectar.ModelExtension
end
end
# Part of Schema Addition DSL
defmacro add_to_schema([do: block]) do
schema_change = Macro.escape(block)
quote bind_quoted: [schema_change: schema_change] do
Module.put_attribute(__MODULE__, :schema_changes, schema_change)
end
end
defmacro __before_compile__(_env) do
quote do
defmacro extensions do
@schema_changes
end
end
end
end
## Service Code
defmodule Nectar.ExtendProduct do
## Makes DSL available defined in library code
use Nectar.ModelExtension
add_to_schema do: (field :special, :boolean, virtual: true)
add_to_schema do: (field :type, :string, virtual: true)
end
defmodule Nectar.Product do
## Make Service Code available to be consumed
## through Library Code
import Nectar.ExtendProduct
schema do
## Service Consumer Code
extensions
end
## Add #special boolean to get casted
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, ~w(special))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment