Skip to content

Sane conventions for using ExAirtable with Ecto for schema validation.

Notifications You must be signed in to change notification settings

dmerand/ex_airtable_phoenix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ExAirtablePhoenix

A set of sensible defaults for using ExAirtable with Phoenix, using Ecto's embedded schemas for validation.

The overall goal is to make working with ExAirtable in Phoenix projects similar enough to working with Ecto to provide a migration pathway should your app outgrow Airtable as a back-end. At the same time, many (most?) apps will never come close to outgrowing Airtable, so you might as well have a nice time using it :)

Because ExAirtable returns general-purpose structs that conform to the Airtable API specifications, it's often nice to be able to further validate those structs to domain-specific models. For example, ExAirtable might return something like this for your "blogging" app:

%ExAirtable.Airtable.Record{
  createdTime: "2016-05-20T01:00:23.000Z",
  fields: %{
    "Email" => "[email protected]",
    "Comments" => ["recg6cWUjaSxrShNy", "recE2sCYzvbgbDUAZ",
     "recJyXQOKlQRS38n7"],
    "Name" => "Some App User",
    "Useless Field" => "Whatever"
  },
  id: "recIbeH41sLn4nF6t"
}

...when what you really want is something more like this:

%MyApp.User{
  name: "Some App User",
  email: "[email protected]",
  comments: [%MyApp.Comment{}, %MyApp.Comment{}, ...]
}

The thinking is, since Ecto has such nice embedded schema support, why reinvent the wheel? This library allows you to do a relatively small amount of setup by defining models that link to Airtable, optionally filter the resulting values, and then use Ecto embedded schemas to validate and cast them into domain models.

Continuing the above "blogging" app example, you might have a model defined like this:

defmodule MyApp.User do
  use ExAirtable.Phoenix.Model
  
  # Details about your Base
  def base do
    %ExAirtable.Config.Base{
      api_key: "your key",
      id: "your base ID"
    }
  end

  # This would be the name of the table in your Airtable base
  @impl ExAirtable.Table
  def name, do: "Users"

  # Convert the Airtable field names to your app's field names.
  @impl ExAirtable.Table
  def schema do
    %{
      "Email" => :email,
      "First Name" => :first_name,
      "Last Name" => :last_name
    }
  end

  # This is Ecto, doing the work of casting and schema definition
  embedded_schema do
    field(:airtable_id, :string)
    field(:email, :string)
    field(:first_name, :string)
    field(:last_name, :string)
  end

  @doc """
  Returns a `%User{}` given a valid set of attributes.
  On failure, returns `{:error, %Ecto.Changeset{}}`
  """
  @impl ExAirtable.Phoenix.Model
  def validate(attrs \\ %{}) do
    %__MODULE__{}
    |> cast(attrs, [:airtable_id, :email, :first_name, :last_name])
    |> validate_required([:airtable_id, :email, :first_name])
    |> apply_action(:save)
  end
end

Once you've defined your model object this way, you can use the functions in ExAirtable.Phoenix.Repo to automatically retrieve, convert, etc. items out of your ExAirtable cache:

defmodule MyApp.UserContext do
  alias ExAirtable.Phoenix.Repo
  alias MyApp.User
  
  @doc """
  Find a User by email

  Returns `{:ok, %User{}}` on success.

  Returns `{:error, :not_found}` on failure.
  """
  def find_by_email(email) do
    if user = Repo.one(User, :email, email) do
        {:ok, user}
    else
        {:error, :not_found}
    end
  end

  @doc """
  List all valid users
  """
  def list_users do
    Repo.all(User)
  end
end

Be sure to check out ExAirtable.Phoenix.Repo for more details and examples. Also, make sure to look at the ExAirtable docs themselves for more information about how you configure ExAirtable for your app.

Installation

If available in Hex, the package can be installed by adding ex_airtable_phoenix to your list of dependencies in mix.exs:

def deps do
  [
    {:ex_airtable_phoenix, "~> 0.1.0"}
  ]
end

If you prefer to use the latest build, point straight to github:

  [
    {:ex_airtable_phoenix, git: "https://github.com/dmerand/ex_airtable_phoenix.git"}
  ]

Documentation

More documentation can be found at https://hexdocs.pm/ex_airtable_phoenix.

About

Sane conventions for using ExAirtable with Ecto for schema validation.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages