<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="318986" data-post-id="318986">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="voughtdq" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/voughtdq/120/9633_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  voughtdq
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Saša’s article made me wish that every function in <code>Ecto.Repo</code> were overrideable. I’m not really a fan of <code>fetch</code>/<code>transact</code>, so would prefer to override <code>one</code>/<code>get</code>/<code>get_by</code>/<code>transaction</code> instead.</p>
<p>I get that this is largely incompatible with the way things work, but I wish there were some solution that basically allowed me to override parts of <code>Ecto.Repo</code> but keep everything else. The only way I could figure out how to do it was to create a wrapper module.</p>
<p>Wrapping has its problems though - I have to <code>defdelegate</code> all non-overrided functions to the <code>BaseRepo</code> module <em>and</em> reference <code>BaseRepo</code> for configuration.</p>
<p>I wish there were a way to tell Ecto that I’m wrapping a repo so whenever it sees <code>WrappedRepo</code> it would actually use <code>BaseRepo</code> for config and the “private” functions (e.g. <code>Ecto.Repo.Schema.insert(...)</code>).</p>
<p>It’s not really <em>that</em> big of a deal, but Ecto letting us define custom wrappers around the repo would really improve code ergonomics. I’m fine with handling the incompatibility of external libraries expecting the repo to work like a normal non-overrided repo.</p>
<p>If the code police is reading this, I plead the fifth. If you have any ideas about how to do what I’m trying to do, I definitely want to hear them.</p>
<details>
<summary>
bad, illegal, offensive code</summary>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule DM.Repo do
  alias DM.BaseRepo

  def one(queryable, opts \\ []) do
    case BaseRepo.one(queryable, opts) do
      nil -&gt; {:error, :not_found}
      record -&gt; {:ok, record}
    end
  end

  def get(queryable, id, opts \\ []) do
    case BaseRepo.get(queryable, id, opts) do
      nil -&gt; {:error, :not_found}
      record -&gt; {:ok, record}
    end
  end

  def get_by(queryable, clauses, opts \\ []) do
    case BaseRepo.get_by(queryable, clauses, opts) do
      nil -&gt; {:error, :not_found}
      record -&gt; {:ok, record}
    end
  end

  def transaction(fun, opts \\ []) when is_function(fun) do
    BaseRepo.transaction(
      fn repo -&gt;
        result =
          case Function.info(fun, :arity) do
            {:arity, 0} -&gt; fun.()
            {:arity, 1} -&gt; fun.(repo)
          end

        case result do
          {:ok, result} -&gt; result
          {:error, reason} -&gt; repo.rollback(reason)
        end
      end,
      opts
    )
  end

  # query API
  defdelegate aggregate(queryable, aggregate, opts \\ []), to: BaseRepo
  defdelegate aggregate(queryable, aggregate, field, opts), to: BaseRepo
  defdelegate all(queryable, opts \\ []), to: BaseRepo
  defdelegate delete_all(queryable, opts \\ []), to: BaseRepo
  defdelegate exists?(queryable, opts \\ []), to: BaseRepo
  defdelegate get!(queryable, id, opts \\ []), to: BaseRepo
  defdelegate get_by!(queryable, clauses, opts \\ []), to: BaseRepo
  defdelegate one!(queryable, opts \\ []), to: BaseRepo
  defdelegate stream(queryable, opts \\ []), to: BaseRepo
  defdelegate update_all(queryable, updates, opts \\ []), to: BaseRepo

  # schema API
  defdelegate delete(struct_or_changeset, opts \\ []), to: BaseRepo
  defdelegate delete!(struct_or_changeset, opts \\ []), to: BaseRepo
  defdelegate insert(struct_or_changeset, opts \\ []), to: BaseRepo
  defdelegate insert!(struct_or_changeset, opts \\ []), to: BaseRepo
  defdelegate insert_all(schema_or_source, entries_or_query, opts \\ []), to: BaseRepo
  defdelegate insert_or_update(changeset, opts \\ []), to: BaseRepo
  defdelegate insert_or_update!(changeset, opts \\[]), to: BaseRepo
  defdelegate load(schema_or_map, data), to: BaseRepo
  defdelegate preload(structs_or_struct_or_nil, preloads, opts \\ []), to: BaseRepo
  defdelegate reload(struct_or_structs, opts \\ []), to: BaseRepo
  defdelegate reload!(struct_or_structs, opts \\ []), to: BaseRepo
  defdelegate update(changeset, opts \\ []), to: BaseRepo
  defdelegate update!(changeset, opts \\ []), to: BaseRepo

  # transaction API
  defdelegate checked_out?(), to: BaseRepo
  defdelegate checkout(function, opts \\ []), to: BaseRepo
  defdelegate in_transaction?(), to: BaseRepo
  defdelegate rollback(value), to: BaseRepo

  # runtime API
  defdelegate __adapter__(), to: BaseRepo
  defdelegate get_dynamic_repo(), to: BaseRepo
  defdelegate put_dynamic_repo(name_or_pid), to: BaseRepo
  defdelegate start_link(opts \\ []), to: BaseRepo
  defdelegate stop(timeout \\ 5000), to: BaseRepo

  defdelegate disconnect_all(interval, opts \\ []), to: BaseRepo
  defdelegate explain(type, query, opts \\ []), to: BaseRepo
  defdelegate query(sql, params, opts \\ []), to: BaseRepo
  defdelegate query!(sql, params, opts \\ []), to: BaseRepo
  defdelegate query_many(sql, params, opts \\ []), to: BaseRepo
  defdelegate query_many!(sql, params, opts \\ []), to: BaseRepo
  defdelegate to_sql(type, query), to: BaseRepo

end

defmodule DM.BaseRepo do
  use Ecto.Repo,
  otp_app: :dm,
  adapter: Ecto.Adapters.Postgres
end
</code></pre>
</details> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="318986" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/seeking-thoughts-on-advantages-of-the-repo-transact-pattern-vs-disadvantages-i-ve-read-about-ecto-multi/61733/32">Post #31</a>
	                </div>
	            </div>
              <div id="likers-container-318986" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="318986"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #31"></div>
  </section>
</div>
    <div class="postbit" id="318987" data-post-id="318987">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="LostKobrakai" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/LostKobrakai/120/3072_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  LostKobrakai
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>You can overwrite or extend repo generated functions, but ding so will be very confusing to the next developer working on that project.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="318987" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/seeking-thoughts-on-advantages-of-the-repo-transact-pattern-vs-disadvantages-i-ve-read-about-ecto-multi/61733/33">Post #32</a>
	                </div>
	            </div>
              <div id="likers-container-318987" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="318987"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #32"></div>
  </section>
</div>
    <div class="postbit" id="318993" data-post-id="318993">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="voughtdq" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/voughtdq/120/9633_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  voughtdq
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><em>(I’m kind of going off-topic now, sorry)</em></p>
<aside class="quote no-group" data-username="LostKobrakai" data-post="33" data-topic="61733" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/48/3072_2.png" class="avatar"> LostKobrakai:</div>
<blockquote>
<p>You can overwrite or extend repo generated functions, but ding so will be very confusing to the next developer working on that project.</p>
</blockquote>
</aside>
<p>The way to overwrite is a little too workaroundy for me -</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># after `use Ecto.Repo, ...`
warning: this clause for get/3 cannot match because a previous clause at line 6 always matches
  lib/app/repo.ex:46

# before `use Ecto.Repo, ...`
warning: this clause for get/3 cannot match because a previous clause at line 6 always matches
  lib/app/repo.ex:20
</code></pre>
<p>(and the other warnings you get when functions aren’t grouped together)</p>
<p>If accidentally defined after <code>use</code>, the function clause won’t match.</p>
<p>This did remind me that it’s just a behaviour, but still pretty crunchy to have to redefine everything. Still workable though.</p>
<p>I think these changes to the repo wouldn’t be too surprising since it would be ubiquitous in the codebase.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="318993" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/seeking-thoughts-on-advantages-of-the-repo-transact-pattern-vs-disadvantages-i-ve-read-about-ecto-multi/61733/34">Post #33</a>
	                </div>
	            </div>
              <div id="likers-container-318993" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="318993"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #33"></div>
  </section>
</div>
    <div class="postbit" id="318999" data-post-id="318999">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="voughtdq" data-post="32" data-topic="61733">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/voughtdq/48/9633_2.png" class="avatar"> voughtdq:</div>
<blockquote>
<p>If you have any ideas about how to do what I’m trying to do</p>
</blockquote>
</aside>
<p>Don’t do that because it’s changing the accepted behavior of well-known functions. People will find this very confusing. Instead define new functions, such as <code>Repo.fetch</code>, <code>Repo.fetch_one</code>, <code>Repo.fetch_by</code>…</p>
<p>Btw, the implementation you provided has subtle issue. If the <code>queryable</code> selects an existing <code>nil</code> (e.g. <code>from foo in Foo, select: foo.bar</code>, where the row exists but the value of <code>bar</code> is <code>nil</code>), these functions would return <code>{:error, :not_found}</code>, which is incorrect.</p>
<p>What you want to do instead is something like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">case Repo.all(queryable, opts) do
  [record] -&gt; {:ok, record}
  [] -&gt; :error
  other -&gt; raise Ecto.MultipleResultsError, queryable: queryable, count: length(other)
end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="318999" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/seeking-thoughts-on-advantages-of-the-repo-transact-pattern-vs-disadvantages-i-ve-read-about-ecto-multi/61733/35">Post #34</a>
	                </div>
	            </div>
              <div id="likers-container-318999" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="318999"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #34"></div>
  </section>
</div>
    <div class="postbit" id="319000" data-post-id="319000">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="LostKobrakai" data-post="6" data-topic="61733">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/48/3072_2.png" class="avatar"> LostKobrakai:</div>
<blockquote>
<p>I truely think the only thing problematic with <code>Repo.transaction(fn -&gt; … end)</code> is the return value mapping – no explicit error return and requiring exceptions – which is what <code>Repo.transact</code> does change.</p>
</blockquote>
</aside>
<p>Yes, the API was designed to mirror databases: if you rollback, you immediately return to the state before the transaction. I am sure it was also designed before <code>with</code> was added to the language. <img src="https://forum.elixirforum.com/images/emoji/apple/smiley.png?v=15" title=":smiley:" class="emoji" alt=":smiley:" loading="lazy" width="20" height="20"></p>
<p>There is still one benefit of <code>Ecto.Multi</code> in that it immediately aborts in case of errors. This is important because if an insert fails, the transaction is aborted, and you can’t do anything else useful in there. This means, that if someone were to write this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Repo.transaction(fn -&gt;
  with {:ok, user} &lt;- insert_user(),
       {:ok, compant} &lt;- insert_company() do
    ...
  else
    :error -&gt; # do another query
  end
end)
</code></pre>
<p>Whatever you do on the else branch won’t work. But this is already a problem with Repo.transaction, just not with Ecto.Multi.</p>
<aside class="quote no-group" data-username="voughtdq" data-post="32" data-topic="61733">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/voughtdq/48/9633_2.png" class="avatar"> voughtdq:</div>
<blockquote>
<p>Saša’s article made me wish that every function in <code>Ecto.Repo</code> were overrideable. I’m not really a fan of <code>fetch</code>/<code>transact</code>, so would prefer to override <code>one</code>/<code>get</code>/<code>get_by</code>/<code>transaction</code> instead.</p>
</blockquote>
</aside>
<p>I can understand wanting to override <code>one</code> or <code>transaction</code>, but overriding <code>get</code> by <code>fetch</code> would be very confusing. <code>get</code> in Repo behaves consistently with all <code>get</code>s in the language: it returns the value, not ok/error tuples.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="319000" data-batch-url="/posts/batch_likers">
                        5
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/seeking-thoughts-on-advantages-of-the-repo-transact-pattern-vs-disadvantages-i-ve-read-about-ecto-multi/61733/36">Post #35</a>
	                </div>
	            </div>
              <div id="likers-container-319000" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="319000"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #35"></div>
  </section>
</div>
    <div class="postbit" id="319001" data-post-id="319001">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="fmn" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fmn/120/26825_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  fmn
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sasajuric" data-post="9" data-topic="61733">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>The fact that the 2nd insert is performed only if the 1st one succeeds is now not so obvious. It is a custom special behaviour of the library code (presumably handled by <code>Repo.transaction</code>).</p>
<p>So control-flow mechanism is now special. Outside of db transactions we use vanilla Elixir. Inside, we use the custom mechanism of multi. This is confusing. Why do I have to use different approaches to early-exit depending on whether I’m inside an Ecto transaction or not?</p>
</blockquote>
</aside>
<p>i am not sure if i agree with this one, feels subjective.<br>
for me creating a struct and using it as a vessel to gather changes before doing something with them feels right - even if this is not exactly what happens in technical terms. i like to think same way about Plug pipelines in Phoenix.</p>
<p>on top of that, this is semantics you will see in most if not all transactional RDBMSes: you open a transaction, you are doing stuff, and either all passed or none.</p>
<p>if you play with RDBMS and transactions, you really need to be aware of this.<br>
i understand argument that it’s tempting to cover external functionality “native” way, with primitives language provides out of the box (i actually preach it quite often), but this won’t and can’t replace awareness of RDBMS semantics. in best case, if you are fairly successful you will build an abstraction which has mental cost to it. is it worth it? what’s the gain? i am not sure.</p>
<p>an anecdote: i witnessesed whole generation of enterprise Java developers taking a shortcut (for multiple reasons) using ORMs as a replacement and not an addition to RDBMS, and results were often tragic.</p>
<p>(as a side-note: my default reflex is to trust you, more than my own brain, so i will be getting back to what you wrote in this thread whenever i deal with the subject in anger <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20">)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="319001" data-batch-url="/posts/batch_likers">
                        5
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/seeking-thoughts-on-advantages-of-the-repo-transact-pattern-vs-disadvantages-i-ve-read-about-ecto-multi/61733/37">Post #36</a>
	                </div>
	            </div>
              <div id="likers-container-319001" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="319001"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #36"></div>
  </section>
</div>
    <div class="postbit" id="319013" data-post-id="319013">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sodapopcan" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sodapopcan/120/34668_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sodapopcan
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="voughtdq" data-post="32" data-topic="61733">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/voughtdq/48/9633_2.png" class="avatar"> voughtdq:</div>
<blockquote>
<p>Saša’s article made me wish that every function in <code>Ecto.Repo</code> were overrideable.</p>
</blockquote>
</aside>
<p>Which article?  Was looking through this thread and can’t find it.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="36" data-topic="61733">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p><code>get</code> in Repo behaves consistently with all <code>get</code>s in the language: it returns the value, not ok/error tuples.</p>
</blockquote>
</aside>
<aside class="quote no-group" data-username="sasajuric" data-post="35" data-topic="61733">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>Don’t do that because it’s changing the accepted behavior of well-known functions.</p>
</blockquote>
</aside>
<p>More to the point, don’t <code>get</code>, <code>one</code>, and <code>all</code> return <code>nil</code> (or <code>[nil]</code>) because a query that returns 0 results is <em>not an error</em>?  It’s a <em>successful</em> query that returned zero rows represented by <code>nil</code>.  I’ve always operated under the idea that <code>:ok/:error</code> tuples describe the result of some side effect not under our control <em>or</em> a pure function that receives data we don’t control, like passing user-generated HTML to <code>Floki.parse_document</code>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="319013" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/seeking-thoughts-on-advantages-of-the-repo-transact-pattern-vs-disadvantages-i-ve-read-about-ecto-multi/61733/38">Post #37</a>
	                </div>
	            </div>
              <div id="likers-container-319013" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="319013"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #37"></div>
  </section>
</div>
    <div class="postbit" id="319014" data-post-id="319014">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dimitarvp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/120/38664_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dimitarvp
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sodapopcan" data-post="38" data-topic="61733">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sodapopcan/48/34668_2.png" class="avatar"> sodapopcan:</div>
<blockquote>
<p>Which article? Was looking through this thread and can’t find it.</p>
</blockquote>
</aside>
<p>It’s linked inside the article I posted in the OP (changed medium to scribe):</p>
<p><a href="https://scribe.rip/very-big-things/towards-maintainable-elixir-the-core-and-the-interface-c267f0da43" class="onebox" target="_blank" rel="noopener nofollow ugc">https://scribe.rip/very-big-things/towards-maintainable-elixir-the-core-and-the-interface-c267f0da43</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="319014" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/seeking-thoughts-on-advantages-of-the-repo-transact-pattern-vs-disadvantages-i-ve-read-about-ecto-multi/61733/39">Post #38</a>
	                </div>
	            </div>
              <div id="likers-container-319014" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="319014"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #38"></div>
  </section>
</div>
    <div class="postbit" id="319018" data-post-id="319018">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sodapopcan" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sodapopcan/120/34668_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sodapopcan
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Double thank you for introducing me to scribe, holy heck!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="319018" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/seeking-thoughts-on-advantages-of-the-repo-transact-pattern-vs-disadvantages-i-ve-read-about-ecto-multi/61733/40">Post #39</a>
	                </div>
	            </div>
              <div id="likers-container-319018" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="319018"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #39"></div>
  </section>
</div>
    <div class="postbit" id="319023" data-post-id="319023">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="36" data-topic="61733">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>There is still one benefit of <code>Ecto.Multi</code> in that it immediately aborts in case of errors. This is important because if an insert fails, the transaction is aborted, and you can’t do anything else useful in there.</p>
</blockquote>
</aside>
<p>This is a great point, and in light of that multi seems more reasonable. On the other hand, we can also see how these limitations of DBs spill over to affect the Elixir code. We end up with this more declarative design, and clumsy value threading via the assigns-like map.</p>
<p>In the mentioned issue (trying to do something useful after a failed db operation), I assume that any subsequent attempt to do a db operation, or to commit a transaction, would raise, right?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="319023" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/seeking-thoughts-on-advantages-of-the-repo-transact-pattern-vs-disadvantages-i-ve-read-about-ecto-multi/61733/41">Post #40</a>
	                </div>
	            </div>
              <div id="likers-container-319023" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="319023"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #40"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/61733/load_more?page=5">Load more posts (16 remaining)</a>
</div></template></turbo-stream>