Drops.Relation.Plugins.Writing (drops_relation v0.1.0)

View Source

Plugin that provides writing operations for relation modules.

This plugin adds Ecto.Repo-like functions for creating, updating, and deleting data:

All functions delegate to the corresponding Ecto.Repo functions with automatic repository and relation configuration.

Examples

iex> {:ok, user} = MyApp.Users.insert(%{name: "Alice", email: "alice.new@example.com", age: 28, active: true})
iex> user.name
"Alice"
iex> user.email
"alice.new@example.com"

iex> # Insert with changeset
iex> changeset = MyApp.Users.changeset(%{name: "Charlie", email: "charlie.new@example.com", age: 32, active: true})
iex> {:ok, user} = MyApp.Users.insert(changeset)
iex> user.name
"Charlie"

iex> # Update existing user
iex> existing_user = MyApp.Users.get(1)
iex> {:ok, updated_user} = MyApp.Users.update(existing_user, %{name: "John Updated"})
iex> updated_user.name
"John Updated"

iex> # Delete user
iex> user_to_delete = MyApp.Users.get(2)
iex> {:ok, deleted_user} = MyApp.Users.delete(user_to_delete)
iex> deleted_user.name
"Jane Smith"

Summary

Functions

Creates a changeset from a map and opts.

Deletes a struct.

Deletes a struct, raises on error.

Inserts a new record into the database.

Inserts a struct, changeset, or plain map, raises on error.

Inserts all entries into the repository.

Reloads a struct from the database.

Reloads a struct from the database, raises on error.

Updates a changeset.

Updates a struct with the given attributes.

Updates a changeset, raises on error.

Updates a struct with the given attributes, raises on error.

Functions

changeset(params, opts)

Creates a changeset from a map and opts.

Uses the relation schema to automatically cast fields based on their types. The changeset can be used for validation and database operations.

Parameters

  • params - Map of parameters to cast into a changeset
  • opts - Additional options (optional, defaults to [])

Options

  • :empty_values - A list of values to be considered as empty when casting
  • :force_changes - A boolean indicating whether to include values that don't alter the current data

Returns

An Ecto.Changeset struct with the cast parameters.

Examples

iex> changeset = MyApp.Users.changeset(%{name: "Frank", email: "frank.changeset@example.com", age: 31, active: true})
iex> changeset.valid?
true
iex> changeset.changes.name
"Frank"
iex> changeset.changes.email
"frank.changeset@example.com"

iex> # With existing struct
iex> user = MyApp.Users.get(1)
iex> changeset = MyApp.Users.changeset(user, %{name: "John Updated Again"})
iex> changeset.changes.name
"John Updated Again"

See Ecto.Changeset.cast/4 for more details.

changeset(struct, params, opts)

delete(struct, opts)

Deletes a struct.

Delegates to Ecto.Repo.delete/2. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Parameters

  • struct - The struct to delete
  • opts - Additional options (optional, defaults to [])

Options

  • :repo - Override the default repository
  • :timeout - Query timeout in milliseconds
  • :log - Override logging configuration

Returns

  • {:ok, struct} - Successfully deleted record
  • {:error, changeset} - Database errors

Examples

iex> user = MyApp.Users.get(3)
iex> {:ok, deleted_user} = MyApp.Users.delete(user)
iex> deleted_user.name
"Bob Wilson"
iex> deleted_user.id
3

See Ecto.Repo.delete/2 for more details.

delete!(struct, opts)

Deletes a struct, raises on error.

Delegates to Ecto.Repo.delete!/2. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Examples

user = MyRelation.delete!(user)
user = MyRelation.delete!(user, repo: AnotherRepo)

See Ecto.Repo.delete!/2 for more details.

insert(struct_or_changeset, opts \\ [])

@spec insert(
  struct() | Ecto.Changeset.t() | map(),
  keyword()
) :: {:ok, struct()} | {:error, Ecto.Changeset.t()}

Inserts a new record into the database.

This function accepts a struct, changeset, or plain map and inserts it into the database. When given a plain map, it automatically creates a struct using the relation's schema. Returns a tuple with the operation result.

Parameters

  • struct_or_changeset - The data to insert (struct, changeset, or plain map)
  • opts - Additional options (optional, defaults to [])

Options

  • :repo - Override the default repository
  • :timeout - Query timeout in milliseconds
  • :log - Override logging configuration
  • :returning - Fields to return from the inserted record
  • :on_conflict - How to handle conflicts (e.g., :raise, :nothing, :replace_all)

Returns

  • {:ok, struct} - Successfully inserted record
  • {:error, changeset} - Validation or database errors

Examples

iex> # Insert with plain map
iex> {:ok, user} = MyApp.Users.insert(%{name: "David", email: "david.test@example.com", age: 29, active: true})
iex> user.name
"David"
iex> user.email
"david.test@example.com"

iex> # Insert with changeset
iex> changeset = MyApp.Users.changeset(%{name: "Emma", email: "emma.test@example.com", age: 26, active: true})
iex> {:ok, user} = MyApp.Users.insert(changeset)
iex> user.name
"Emma"

Validation

If the data fails validation, returns {:error, changeset} with detailed error information:

{:error, changeset} = Users.insert(%{email: "invalid-email"})
changeset.errors
# => [email: {"has invalid format", [validation: :format]}]

See Ecto.Repo.insert/2 for more details on the underlying implementation.

insert!(struct_or_changeset, opts)

Inserts a struct, changeset, or plain map, raises on error.

Delegates to Ecto.Repo.insert!/2. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Parameters

  • struct_or_changeset - A struct, changeset, or plain map to insert
  • opts - Additional options (optional, defaults to [])

Options

  • :repo - Override the default repository
  • :timeout - Query timeout in milliseconds
  • :log - Override logging configuration
  • :returning - Fields to return from the inserted record
  • :on_conflict - How to handle conflicts (e.g., :raise, :nothing, :replace_all)

Returns

The inserted record struct, raises on error.

Examples

iex> user = MyApp.Users.insert!(%{name: "Alice", email: "alice.unique@example.com", age: 28, active: true})
iex> user.name
"Alice"
iex> user.email
"alice.unique@example.com"

iex> # Insert with changeset
iex> changeset = MyApp.Users.changeset(%{name: "Bob", email: "bob.unique@example.com", age: 35, active: false})
iex> user = MyApp.Users.insert!(changeset)
iex> user.name
"Bob"

See Ecto.Repo.insert!/2 for more details.

insert_all(entries, opts)

Inserts all entries into the repository.

Delegates to Ecto.Repo.insert_all/3. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Examples

{count, structs} = MyRelation.insert_all([%{name: "John"}, %{name: "Jane"}])
{count, structs} = MyRelation.insert_all(entries, repo: AnotherRepo)

See Ecto.Repo.insert_all/3 for more details.

reload(struct, opts)

Reloads a struct from the database.

Delegates to Ecto.Repo.reload/2. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Examples

user = MyRelation.reload(user)
user = MyRelation.reload(user, repo: AnotherRepo)

See Ecto.Repo.reload/2 for more details.

reload!(struct, opts)

Reloads a struct from the database, raises on error.

Delegates to Ecto.Repo.reload!/2. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Examples

user = MyRelation.reload!(user)
user = MyRelation.reload!(user, repo: AnotherRepo)

See Ecto.Repo.reload!/2 for more details.

update(changeset, opts)

Updates a changeset.

Delegates to Ecto.Repo.update/2. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Examples

{:ok, user} = MyRelation.update(changeset)
{:ok, user} = MyRelation.update(changeset, repo: AnotherRepo)

See Ecto.Repo.update/2 for more details.

update(struct, attributes, opts)

Updates a struct with the given attributes.

Creates a changeset from the struct and attributes, then delegates to Ecto.Repo.update/2. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Parameters

  • struct - The struct to update
  • attributes - Map of attributes to update
  • opts - Additional options (optional, defaults to [])

Options

  • :repo - Override the default repository
  • :timeout - Query timeout in milliseconds
  • :log - Override logging configuration
  • :force_changes - Force changes even if values haven't changed

Returns

  • {:ok, struct} - Successfully updated record
  • {:error, changeset} - Validation or database errors

Examples

iex> user = MyApp.Users.get(1)
iex> {:ok, updated_user} = MyApp.Users.update(user, %{name: "John Updated"})
iex> updated_user.name
"John Updated"

iex> # Update with multiple attributes
iex> user = MyApp.Users.get(2)
iex> {:ok, updated_user} = MyApp.Users.update(user, %{name: "Jane Updated", age: 26})
iex> updated_user.name
"Jane Updated"
iex> updated_user.age
26

See Ecto.Repo.update/2 for more details.

update!(changeset, opts)

Updates a changeset, raises on error.

Delegates to Ecto.Repo.update!/2. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Examples

user = MyRelation.update!(changeset)
user = MyRelation.update!(changeset, repo: AnotherRepo)

See Ecto.Repo.update!/2 for more details.

update!(struct, attributes, opts)

Updates a struct with the given attributes, raises on error.

Creates a changeset from the struct and attributes, then delegates to Ecto.Repo.update!/2. The :repo and :relation options are automatically set based on the repository and relation module configured in the use macro, but can be overridden.

Examples

user = MyRelation.update!(user_struct, %{name: "Jane"})
user = MyRelation.update!(user_struct, %{name: "Jane"}, repo: AnotherRepo)

See Ecto.Repo.update!/2 for more details.