From fdf2ed13446cdc68f5bd6025eda1936428181f57 Mon Sep 17 00:00:00 2001 From: MikaAK Date: Fri, 26 Jul 2024 01:21:28 -0700 Subject: [PATCH] chore: update docs --- lib/actions.ex | 45 ++++++++++++++++++++++++++++++++++++ lib/common_changes.ex | 53 ++++++++++++++++++++++++++++++++++++++++++- lib/ecto_shorts.ex | 2 +- 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/lib/actions.ex b/lib/actions.ex index 350eff4..5e3589d 100644 --- a/lib/actions.ex +++ b/lib/actions.ex @@ -1,6 +1,51 @@ defmodule EctoShorts.Actions do @moduledoc """ Actions for CRUD in ecto, these can be used by all schemas/queries + + Generally we can define our contexts to be very reusable by creating + them to look something like this: + + + defmodule MyApp.Accounts do + alias EctoShorts.Actions + alias MyApp.Accounts.User + + def all_users(params), do: Actions.all(User, params) + def find_user(params), do: Actions.find(User, params) + end + + We're then able to use this context with all filters that are + supported by `EctoShorts.CommonFilters` without having to create new queries + + + def do_something do + MyApp.Accounts.all_user(%{ + first_name: %{ilike: "john"}, + age: %{gte: 18}, + priority_level: 5, + address: %{country: "Canada"} + }) + end + + + You can read more on reusable ecto code [here](https://learn-elixir.dev/blogs/creating-reusable-ecto-code) + + ### Supporting multiple Repos + + To support multiple repos, what we can do is pass arguments to the last parameter + of most `EctoShorts.Actions` calls + + #### Example + + defmodule MyApp.Accounts do + alias EctoShorts.Actions + alias MyApp.Accounts.User + + @repo [repo: MyApp.Repo.Replica1] + + def all_users(params), do: Actions.all(User, params, @repo) + def find_user(params), do: Actions.find(User, params, @repo) + end """ @type query :: Ecto.Query.t() | Ecto.Schema.t()| module() diff --git a/lib/common_changes.ex b/lib/common_changes.ex index f7ab84d..431c744 100644 --- a/lib/common_changes.ex +++ b/lib/common_changes.ex @@ -1,6 +1,57 @@ defmodule EctoShorts.CommonChanges do @moduledoc """ - This module is responsible for determining put/cast assoc as well as creating and updating model relations + `CommonChanges` is a collection of functions to help with managing + and creating our `&changeset/2` function in our schemas. + + ### Preloading associations on change + Often times we want to be able to change an association with + `(put/cast)_assoc`, but we have an awkwardness of having to use + a preload in a spot to do this. We can aleviate that by doing the following: + + defmodule MyApp.Accounts.User do + def changeset(changeset, params) do + changeset + |> cast([:name, :email]) + |> validate_required([:name, :email]) + |> EctoShorts.CommonChanges.preload_change_assoc(:address) + end + end + + Doing this allows us to then pass address in via a map, or even using + the struct from the database directly to add as a relation + + ### Validating relation is passed in somehow + We can validate for a relation being passed in via id or by using our + preload_change_assoc by doing the following: + + defmodule MyApp.Accounts.User do + def changeset(changeset, params) do + changeset + |> cast([:name, :email, :address_id]) + |> validate_required([:name, :email]) + |> EctoShorts.CommonChanges.preload_change_assoc(:address, + required_when_missing: :address_id + ) + end + end + + ### Conditional functions + We can also run functions when something happens by defining conditional functions like so: + + defmodule MyApp.Accounts.User do + alias EctoShorts.CommonChanges + + def changeset(changeset, params) do + changeset + |> cast([:name, :email, :address_id]) + |> validate_required([:name, :email]) + |> CommonChanges.put_when( + &CommonChanges.changeset_field_nil?(&1, :email), + &put_change(&1, :email, "some_default@gmail.com") + ) + end + end + """ require Logger diff --git a/lib/ecto_shorts.ex b/lib/ecto_shorts.ex index b725a05..cc71080 100644 --- a/lib/ecto_shorts.ex +++ b/lib/ecto_shorts.ex @@ -5,7 +5,7 @@ defmodule EctoShorts do - There are 2 main modules Actions and CommonChanges + There are 2 main modules `EctoShorts.Actions` and `EctoShorts.CommonChanges` ### Actions `EctoShorts.Actions` allows for filters to be constructed from data such as