From 4f0c990019ee5b5d96721958e226519c2a6ee83f Mon Sep 17 00:00:00 2001 From: Tom Conroy Date: Mon, 21 Oct 2024 05:31:51 +0900 Subject: [PATCH] Pass allow_stale opt to assocs (#4528) --- lib/ecto/repo.ex | 10 +++++----- lib/ecto/repo/schema.ex | 2 +- test/ecto/repo_test.exs | 20 +++++++++++++++++++- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lib/ecto/repo.ex b/lib/ecto/repo.ex index 5214d59916..1f0c8da560 100644 --- a/lib/ecto/repo.ex +++ b/lib/ecto/repo.ex @@ -1660,9 +1660,9 @@ defmodule Ecto.Repo do * `:stale_error_message` - The message to add to the configured `:stale_error_field` when stale errors happen, defaults to "is stale". - * `:allow_stale` - Doesn't error if insert is stale. Defaults to `false`. + * `:allow_stale` - Doesn't error when structs are stale. Defaults to `false`. This may happen if there are rules or triggers in the database that - rejects the insert operation. + rejects the insert operation. This option cascades to associations. See the ["Shared options"](#module-shared-options) section at the module documentation for more options. @@ -1863,7 +1863,7 @@ defmodule Ecto.Repo do * `:allow_stale` - Doesn't error if update is stale. Defaults to `false`. This may happen if the struct has been deleted from the database before the update or if there is a rule or a trigger on the database that rejects - the update operation. + the update operation. This option cascades to associations. See the ["Shared options"](#module-shared-options) section at the module documentation for more options. @@ -1909,8 +1909,8 @@ defmodule Ecto.Repo do * `:stale_error_message` - The message to add to the configured `:stale_error_field` when stale errors happen, defaults to "is stale". Only applies to updates. - * `:allow_stale` - Doesn't error if delete is stale. Defaults to `false`. - Only applies to updates. + * `:allow_stale` - Doesn't error when structs are stale. Defaults to `false`. + This option cascades to associations. See the ["Shared options"](#module-shared-options) section at the module documentation for more options. diff --git a/lib/ecto/repo/schema.ex b/lib/ecto/repo/schema.ex index aedc99cf34..6fc921166a 100644 --- a/lib/ecto/repo/schema.ex +++ b/lib/ecto/repo/schema.ex @@ -977,7 +977,7 @@ defmodule Ecto.Repo.Schema do defp assoc_opts([], _opts), do: [] defp assoc_opts(_assocs, opts) do - Keyword.take(opts, [:timeout, :log, :telemetry_event, :prefix]) + Keyword.take(opts, [:timeout, :log, :telemetry_event, :prefix, :allow_stale]) end defp process_parents(changeset, user_changeset, assocs, reset_assocs, adapter, opts) do diff --git a/test/ecto/repo_test.exs b/test/ecto/repo_test.exs index bb6f0d6132..82f5bd99d8 100644 --- a/test/ecto/repo_test.exs +++ b/test/ecto/repo_test.exs @@ -49,7 +49,8 @@ defmodule Ecto.RepoTest do schema "my_schema_child" do field :a, :string - belongs_to :my_schema, MySchemaNoPK, references: :n, foreign_key: :n + belongs_to :my_schema, MySchema + belongs_to :my_schema_no_pk, MySchemaNoPK, references: :n, foreign_key: :n end def changeset(struct, params) do @@ -1130,6 +1131,23 @@ defmodule Ecto.RepoTest do assert {:ok, _} = TestRepo.delete(stale, allow_stale: true) end + test "insert, update allows stale children with :allow_stale option" do + child_schema = + %MySchemaChild{a: "one"} + + stale = + put_in(child_schema.__meta__.context, {:error, :stale}) + |> Ecto.Changeset.change() + + changeset = + %MySchema{id: 1} + |> Ecto.Changeset.change() + |> Ecto.Changeset.put_assoc(:children, [stale]) + + assert {:ok, _} = TestRepo.insert(changeset, allow_stale: true) + assert {:ok, _} = TestRepo.update(changeset, allow_stale: true) + end + test "insert and delete sets schema prefix with struct" do valid = %MySchema{id: 1}