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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>This pattern is very similar to <code>ActiveRecord</code>, the ORM from Ruby on Rails framework.</p>
<p>Basically, you can do things like this</p>
<pre data-code-wrap="ruby"><code class="lang-ruby">User
  .where(is_admin: true)
  .order(email: :asc)
  .update_all(ia_admin: false)
</code></pre>
<p>The context approach is something different, you abstract all the query construction behind the semantic function name and you can explore all the queries just looking into context files.</p>
<p>If you’re going to create “meta” contexts then we’ll go back to the ActiveRecord pattern where queries are constructed elsewhere in your codebase but not in one single place.</p>
<p>Both approaches have pros and cons but I don’t think mixing them is a good idea. For me it’s two completely different things because in one case you have “the right way” and you’re overindulging yourself in all king of helpers and pre-generated code.</p>
<p>I can’t find it right now but can remember when rails had code like <code>def seven(), do: 7</code> and you could write <code>seven.days.ago</code> or something similar. It does create pleasant experience but empirically it’ll end up in a codebase which is implicit and challenging to maintain.</p>
<p>On the other side, I comprehend Elixir approach like be explicit, be flexible, allow user decide what is best and how to approach problems and it work best when you’re experienced engineer. Finally, we have configurable, explicit and flexible interfaces in Elixir ecosystem.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="164761" 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/a-design-pattern-for-more-flexible-context-apis/29238/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-164761" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="164761"
                     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 #11"></div>
  </section>
</div>
    <div class="postbit" id="164765" data-post-id="164765">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="1player" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/1player/120/14000_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  1player
                      <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="achempion" data-post="12" data-topic="29238">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/achempion/48/21179_2.png" class="avatar"> achempion:</div>
<blockquote>
<p>The context approach is something different, you abstract all the query construction behind the semantic function name and you can explore all the queries just looking into context files.</p>
<p>If you’re going to create “meta” contexts then we’ll go back to the ActiveRecord pattern where queries are constructed elsewhere in your codebase but not in one single place.</p>
</blockquote>
</aside>
<p>I haven’t used ActiveRecord in a decade, but the point of contexts is separating the business logic from the rest of the application. Multiple query functions or the design pattern described here are still miles better than the regular usage of ActiveRecord, in that it is usually called in the controllers, making tests more difficult as you then require a database connection.</p>
<p>This pattern comes natural if you need to integrate Absinthe GraphQL + dataloader in your application, and it made sense to me to use the same logic even for regular Ecto consumers that are not necessarily connected to Absinthe.</p>
<p>In any case, as with most design patterns, there is No True Way, and I find having a small amount of functions in my contexts better for tests, as contexts are usually the API/contract to test against, and the fewer the functions, the easier it is to mock against.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="164765" 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/a-design-pattern-for-more-flexible-context-apis/29238/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-164765" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="164765"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>