I’m building a new module for my multi-tenant application and trying to come to terms how a prefix
ideally be passed in. Here is a new style using an opts
keyword list with a required prefix
value. I like this since I could also use a preloads
option for get
style functions letting the caller decide which relationships should be preloaded; I think this preload
style will come in handy for my GraphQL stuff. Anyways would love some API design feedback on this draft:
defmodule Guildflow.Invites do
@moduledoc """
Provides functions for creating invites that will be shared with prospective
members. Using an invite a `Member` account can be created.
"""
alias Guildflow.Invites.{Invite}
alias Guildflow.Repo
@expiration_length_in_seconds 60 * 60 * 24 * 7
@doc """
Generates and stores a fresh invite.
## Options
* `:prefix` - The database prefix to use for the insert. (required)
* `:preloads` - a list of relationships that will be preloaded on the
returned records. (demo of an option that would be on a get style
function)
"""
@spec create_invite(keyword) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
def create_invite(opts \\ []) do
expires_on =
DateTime.utc_now()
|> DateTime.add(@expiration_length_in_seconds, :second)
|> DateTime.truncate(:second)
changeset =
Invite.changeset(%Invite{}, %{
"token" => UUID.uuid4(),
"expires_on" => expires_on
})
Repo.insert(changeset, prefix: prefix_from_options(opts))
end
def register_member_from_invite(_invite) do
end
defp prefix_from_options(opts) do
case Keyword.get(opts, :prefix, []) do
nil ->
throw("required prefix missing")
prefix ->
prefix
end
end
end