In rails you can create a model who does not inherit from ActiveRecord but rather simply imports a few methods for the purpose of validation only. ( Think contact form that is not persisted. )
In that case you can
include ActiveModel::Model
So naturally I was thinking I want to try to do that same with ecto.
At the moment I have this contact form and I wanted your thoughts about a better way to do this.
Controller.
defmodule PolymorphicProductionsWeb.ContactController do
use PolymorphicProductionsWeb, :controller
alias PolymorphicProductions.{Messages, Messages.Contact}
...
def create(conn, %{"contact" => contact_params}) do
case Messages.create_contact(contact_params) do
{:ok, contact} ->
conn
|> put_flash(:info, "Your messages was successfully sent.")
|> redirect(to: Routes.page_path(conn, :index))
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, "new.html",
layout: {PolymorphicProductionsWeb.LayoutView, "full-header.html"},
changeset: changeset
)
end
end
end
Context:
defmodule PolymorphicProductions.Messages do
alias PolymorphicProductions.Messages.Contact
@doc """
Creates a contact message and sends it.
"""
def create_contact(attrs \\ %{}) do
case Contact.changeset(%Contact{}, attrs) do
%{valid?: true} = contact ->
{:ok, contact}
changeset ->
Ecto.Changeset.apply_action(changeset, :insert)
end
end
def change_contact(%Contact{} = contact) do
Contact.changeset(contact, %{})
end
end
Schema:
defmodule PolymorphicProductions.Messages.Contact do
use Ecto.Schema
import Ecto.Changeset
schema "contacts" do
field(:name, :string, virtual: true)
field(:email, :string, virtual: true)
field(:subject, :string, virtual: true)
field(:message, :string, virtual: true)
end
@doc false
def changeset(contact, attrs) do
contact
|> cast(attrs, [:name, :email, :subject, :message])
|> validate_required([:name, :email, :subject, :message])
end
end
At the moment I have a schema who does not really have a table of contacts
and I also do this hack to get the phoenix form helpers to render.
Ecto.Changeset.apply_action(changeset, :insert)