Domain Model Design - `use` vs separate shared module

Hi All,

I’m working on a graphql API and due to the complex nature of the source database am wrapping many of my schema modules in a ‘Model’ module. The modules purpose is to define a struct for the model, and some common functions. Below is an example module…

defmodule Nedql.Sources.EditorAssignment do
  alias __MODULE__
  alias Nedql.Repo
  alias Nedql.Utils
  alias Nedql.Filter
  alias Nedql.Repo.Sources.EditorAssignmentSchema
  import Ecto.Query

  defstruct id: nil,
            editor_assignment_id: nil,
            progserv_id: nil,
            editor_assignment_type: nil,
            employee_id: nil

  def base_query(), do: (from e in EditorAssignmentSchema)
  def preload(query), do:  preload(query, [:editor_assignment_type])

  def get!(id) when is_binary(id), do: get!(
  def get!(id) when is_integer(id), do: get!(
  def get!(id) do
    q = from e in EditorAssignmentSchema,
             where: e.editor_assignment_id == ^id,
             preload: [:editor_assignment_type]
    |> into_struct

  def filtered(%Filter{conditions: []} = filter), do: base_query()
  def filtered(%Filter{} = filter) do
    Nedql.Query.add_clauses(base_query(), filter)

  def into_struct(rows) when is_list(rows) do, &into_struct/1)
  def into_struct(row) do
      id: Decimal.to_integer(row.editor_assignment_id),
      editor_assignment_id: Decimal.to_integer(row.editor_assignment_id),
      editor_assignment_type: Utils.get_in_struct(row, [:editor_assignment_type, :editor_assignment_type_tag]),
      progserv_id: Decimal.to_integer(row.progserv_id),
      employee_id: Decimal.to_integer(row.employee_id),

This is a how many of my models are shaping up. Define a struct and the following functions…

  • base_query
  • preload
  • get!
  • filtered
  • into_struct

Some of this can be dry’d up. I’m wondering if the ease of ‘use’ makes more sense or the explicitness of another module is better.

1 Like