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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mathieuprog" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mathieuprog/120/16860_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mathieuprog
                    <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">
								<p>I made <code>order_by</code> also using dynamic queries and added support for extending <code>order_by</code> with a custom Ecto dynamic query. Example:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">character_length =
  fn (field, get_binding_fun) -&gt;
    {field, binding} = get_binding_fun.(field)
    Ecto.Query.dynamic([{^binding, x}], fragment("character_length(?)", field(x, ^field)))
  end

User
|&gt; QueryBuilder.order_by(asc: &amp;character_length.(:name, &amp;1))
|&gt; Repo.all()
</code></pre>
<p>You’ll have to depend on master branch for the moment though, because I had to inverse the direction order and field:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">QueryBuilder.order_by(User, lastname: :asc)
</code></pre>
<p>becomes</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">QueryBuilder.order_by(User, asc: :lastname)
</code></pre>
<p><img src="https://forum.elixirforum.com/images/emoji/apple/man_facepalming.png?v=15" title=":man_facepalming:" class="emoji only-emoji" alt=":man_facepalming:" 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="221301" 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/querybuilder-compose-ecto-queries-without-effort/27704/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-221301" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="221301"
                     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="221311" data-post-id="221311">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks <a class="mention" href="/u/mathieuprog" rel="nofollow">@mathieuprog</a>!  That’s great.  I’ll try out the master branch and share my implementation with you.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="221311" 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/querybuilder-compose-ecto-queries-without-effort/27704/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-221311" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="221311"
                     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 #12"></div>
  </section>
</div>
    <div class="postbit" id="222204" data-post-id="222204">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/mathieuprog" rel="nofollow">@mathieuprog</a>, here’s a gist where I started expanding the QueryBuilder functionality:</p><aside class="onebox githubgist" data-onebox-src="https://gist.github.com/onomated/36e23eb2fb80669b7e440af2a450ea7f">
  <header class="source">

      <a href="https://gist.github.com/onomated/36e23eb2fb80669b7e440af2a450ea7f" target="_blank" rel="noopener nofollow ugc">gist.github.com</a>
  </header>

  <article class="onebox-body">
    <h4><a href="https://gist.github.com/onomated/36e23eb2fb80669b7e440af2a450ea7f" target="_blank" rel="noopener nofollow ugc">https://gist.github.com/onomated/36e23eb2fb80669b7e440af2a450ea7f</a></h4>



  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<p>It’s currently work in progress as I haven’t added the necessary logic to utilize your changes to <code>order_by</code> in your master branch.  Maybe making <code>QueryBuilder</code> a behavior with default implementations will make extending a lot more straightforward i.e. remove the need to <code>defdelegate</code> functions.</p>
<p>An option to avoid breaking your <code>order_by</code> interface would be to support a map of the order by spec, and just check if its a keyword list or map.  So supporting something along the lines of:</p>
<blockquote>
<p>QueryBuilder.order_by(User, %{direction: :asc, field: :last_name})</p>
</blockquote>
<p>Just a thought.</p>
<p>I’ll expand my search functionality to also utilize your current changes for order_by as well and update the gist afterwards</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="222204" 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/querybuilder-compose-ecto-queries-without-effort/27704/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-222204" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="222204"
                     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 #13"></div>
  </section>
</div>
    <div class="postbit" id="222221" data-post-id="222221">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/mathieuprog" rel="nofollow">@mathieuprog</a> Tested out the custom sql functionality for <code>order_by</code>s and it works great.  I’ve updated the gist above with my QueryBuilder extension module that utilizes dynamic bindings in <code>where</code> and <code>order_by</code> methods.  Looking forward to the next release with these features.</p>
<p>Thanks once again for supporting the ask.  Cheers!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="222221" 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/querybuilder-compose-ecto-queries-without-effort/27704/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-222221" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="222221"
                     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 #14"></div>
  </section>
</div>
    <div class="postbit" id="222284" data-post-id="222284">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mathieuprog" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mathieuprog/120/16860_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mathieuprog
                    <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="onomated" data-post="14" data-topic="27704">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/onomated/48/19537_2.png" class="avatar"> onomated:</div>
<blockquote>
<p>Maybe making <code>QueryBuilder</code> a behavior with default implementations will make extending a lot more straightforward i.e. remove the need to <code>defdelegate</code> functions.</p>
</blockquote>
</aside>
<p>It’s a good idea to offer a module to allow extension! I don’t see how a behaviour would help here as you want to extend the QueryBuilder module with your own custom functions with arbitrary function names.<br>
What we could offer though is some code injection: <code>use QueryBuilder.Extension</code> and this will allow to inject the <code>from_list</code> as well to accept the new custom functions.<br>
If you want to change your codebase already you could make a PR, or you can just wait until I’ll get back into it:)</p>
<aside class="quote no-group quote-modified" data-username="onomated" data-post="14" data-topic="27704">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/onomated/48/19537_2.png" class="avatar"> onomated:</div>
<blockquote>
<p>An option to avoid breaking your <code>order_by</code> interface would be to support a map of the order by spec, and just check if its a keyword list or map. So supporting something along the lines of:</p>
<blockquote>
<p>QueryBuilder.order_by(User, %{direction: :asc, field: :last_name})</p>
</blockquote>
</blockquote>
</aside>
<p>The lib is in alpha so I’m allowed to break it? <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"> But what I will do I think is make a stable version 1.x and it won’t bother anyone. Having e.g. <code>asc: :lastname</code> also follows the Ecto Query API option.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="222284" 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/querybuilder-compose-ecto-queries-without-effort/27704/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-222284" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="222284"
                     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 #15"></div>
  </section>
</div>
    <div class="postbit" id="222292" data-post-id="222292">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="mathieuprog" data-post="16" data-topic="27704">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mathieuprog/48/16860_2.png" class="avatar"> mathieuprog:</div>
<blockquote>
<p>What we could offer though is some code injection: <code>use QueryBuilder.Extension</code> and this will allow to inject the <code>from_list</code> as well to accept the new custom functions.</p>
</blockquote>
</aside>
<p>Interesting.  Can you highlight a bit more about what you’re thinking here?  This is a pattern I haven’t seen.  Not as much of a power user of Elixir just yet, so it’ll be an interesting learning experience.</p>
<aside class="quote no-group" data-username="mathieuprog" data-post="16" data-topic="27704">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mathieuprog/48/16860_2.png" class="avatar"> mathieuprog:</div>
<blockquote>
<p>The lib is in alpha so I’m allowed to break it? <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"> But what I will do I think is make a stable version 1.x and it won’t bother anyone. Having e.g. <code>asc: :lastname</code> also follows the Ecto Query API option.</p>
</blockquote>
</aside>
<p>Great point.  Yes this does align with the Ecto Query API arg scheme.</p>
<p>One issue I have run into is that QueryBuilder assumes atom values are fields.  So queries like this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">args_collected_somewhere = [auth_method: :email, auth_val: "someone@example.com"]
User
|&gt; QueryBuilder.where(args_collected_somewhere)
|&gt; Repo.one!()
</code></pre>
<p>is resolving to the following sql and error:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">SELECT a0.* FROM "users" AS a0 WHERE ((a0."auth_val" = $1) AND (a0."auth_method" = a0."email"))

** (Postgrex.Error) ERROR 42703 (undefined_column) column a0.email does not exist
</code></pre>
<p>This is problematic as I use enums (with <a href="https://github.com/gjaldon/ecto_enum" class="inline-onebox" rel="noopener nofollow ugc">GitHub - gjaldon/ecto_enum: Ecto extension to support enums in models · GitHub</a>) somewhat extensively in my data model, so attempting to “know enum fields” and programmatically convert them to strings first will be tedious.  Is there a way to be explicit about values actually being db columns and only then should they be auto-binded as fields?  I can file an issue if there is no workaround for this at the moment.  This was caught in my regression tests as I’m trying to incorporate <code>QueryBuilder.to_list</code> where this worked fine prior:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">args_collected_somewhere = [auth_method: :email, auth_val: "someone@example.com"]
User
|&gt; Repo.get_by!(args_collected_somewhere)
</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="222292" 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/querybuilder-compose-ecto-queries-without-effort/27704/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-222292" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="222292"
                     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 #16"></div>
  </section>
</div>
    <div class="postbit" id="222423" data-post-id="222423">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mathieuprog" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mathieuprog/120/16860_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mathieuprog
                    <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="onomated" data-post="17" data-topic="27704">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/onomated/48/19537_2.png" class="avatar"> onomated:</div>
<blockquote>
<p>Interesting. Can you highlight a bit more about what you’re thinking here? This is a pattern I haven’t seen.</p>
</blockquote>
</aside>
<p>The idea is to simply inject all those <code>defdelegate</code>s and the <code>from_list</code> function into the custom module. Except if I missed something? <code>use</code> allows you to inject code.</p>
<aside class="quote no-group" data-username="onomated" data-post="17" data-topic="27704">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/onomated/48/19537_2.png" class="avatar"> onomated:</div>
<blockquote>
<p>One issue I have run into is that QueryBuilder assumes atom values are fields.</p>
</blockquote>
</aside>
<p>Nice, obviously I didn’t think about that case:) I think it’s easily solved with some reflection:</p><aside class="onebox allowlistedgeneric" data-onebox-src="https://ecto.hexdocs.pm/Ecto.Schema.html">
  <header class="source">

      <a href="https://ecto.hexdocs.pm/Ecto.Schema.html" target="_blank" rel="noopener nofollow ugc">ecto.hexdocs.pm</a>
  </header>

  <article class="onebox-body">
    

<h3><a href="https://ecto.hexdocs.pm/Ecto.Schema.html" target="_blank" rel="noopener nofollow ugc">Ecto.Schema — Ecto v3.14.0</a></h3>



  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<p>As a note to self, I think I’d also like at some point to implement <code>select</code>, because QueryBuilder is limited to fetching full entities right now.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="222423" 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/querybuilder-compose-ecto-queries-without-effort/27704/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-222423" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="222423"
                     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 #17"></div>
  </section>
</div>
    <div class="postbit" id="222433" data-post-id="222433">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="mathieuprog" data-post="18" data-topic="27704">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mathieuprog/48/16860_2.png" class="avatar"> mathieuprog:</div>
<blockquote>
<p>The idea is to simply inject all those <code>defdelegate</code>s and the <code>from_list</code> function into the custom module. Except if I missed something? <code>use</code> allows you to inject code.</p>
</blockquote>
</aside>
<p>Ah, so the thought is allow clients create an extension module that are passed in to <code>QueryBuilder</code> like so?</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">use QueryBuilder, extension: MyApp.QueryBuilder.SearchFunction
</code></pre>
<p><code>MyApp.QueryBuilder</code></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmacro __using__(opts) do
    extension = Keyword.get(opts, :extension, QueryBuilder.NullExtension)
    # confirm its a module with __using__
    quote do
      require QueryBuilder.Schema
      QueryBuilder.Schema.__using__(unquote(opts))
    
      require unquote(extension)
      unquote(extension).__using__(unquote(opts))
    end
  end
</code></pre>
<p>The clients can use just query builder as currently documented.  No <code>defdelegate</code>s required and no <code>from_list</code> overrides needed.  Its worth a shot, though injecting macros can be complex if the extension macros have other macro operations such as setting module attributes which my extension module does.  It’s worth a try to see how that plays out in my case.</p>
<aside class="quote no-group quote-modified" data-username="mathieuprog" data-post="18" data-topic="27704">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mathieuprog/48/16860_2.png" class="avatar"> mathieuprog:</div>
<blockquote>
<p>Nice, obviously I didn’t think about that case:) I think it’s easily solved with some reflection:<br>
<a href="https://hexdocs.pm/ecto/Ecto.Schema.html#module-reflection" class="inline-onebox" rel="noopener nofollow ugc">Ecto.Schema — Ecto v3.14.0</a></p>
</blockquote>
</aside>
<p>That’s one approach, or introducing <code>:self</code> as a sentinel for the current schema to resolve to a field.  So:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">User
|&gt; QueryBuilder.where([auth_method: :email@self, auth_val: "someone@example.com"])
|&gt; Repo.one!()
</code></pre>
<p>Resolves to the current functionality as today, and:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">User
|&gt; QueryBuilder.where([auth_method: :email, auth_val: "someone@example.com"])
|&gt; Repo.one!()
</code></pre>
<p>works like Ecto does today, while modeling the current association syntax you have.</p>
<p>Thoughts?  Either way, it’s worth creating issues, and I can take a stab at working on the functionality suggested in a new branch or just fork the repo and PR back in after implementing.  Definitely need to address the atom field referencing to use this lib</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="222433" 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/querybuilder-compose-ecto-queries-without-effort/27704/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-222433" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="222433"
                     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 #18"></div>
  </section>
</div>
    <div class="postbit" id="222452" data-post-id="222452">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mathieuprog" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mathieuprog/120/16860_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mathieuprog
                    <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="onomated" data-post="19" data-topic="27704">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/onomated/48/19537_2.png" class="avatar"> onomated:</div>
<blockquote>
<p>Ah, so the thought is allow clients create an extension module that are passed in to <code>QueryBuilder</code> like so?</p>
</blockquote>
</aside>
<p>I thought rather something like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule MyApp.QueryBuilder do
  use QueryBuilder.Extension # inject defdelegate and from_list

  def search(query, field, search_term) do
    # code
  end
end
</code></pre>
<p>and in <code>QueryBuilder.Extension</code> have <code>__using__</code> injecting the <code>defdelegate</code>s and <code>from_list</code>.</p>
<p>Except if I’m missing something <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>Note that it really is for the <code>from_list</code> function, otherwise I would have suggested to not extend <code>QueryBuilder</code> at all with macros, and just do something like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">User
|&gt; QueryBuilder.where(firstname: "John")
|&gt; QueryBuilderExt.search(...)
</code></pre>
<p>However the user might want to use <code>from_list</code> with the new functionality.</p>
<aside class="quote no-group" data-username="onomated" data-post="19" data-topic="27704">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/onomated/48/19537_2.png" class="avatar"> onomated:</div>
<blockquote>
<p>That’s one approach, or introducing <code>:self</code> as a sentinel for the current schema to resolve to a field.</p>
</blockquote>
</aside>
<p>I prefer reflection because I think it’s not expensive at all, as I think the values from these functions for reflection are calculated at compile time.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="222452" 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/querybuilder-compose-ecto-queries-without-effort/27704/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-222452" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="222452"
                     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 #19"></div>
  </section>
</div>
    <div class="postbit" id="222472" data-post-id="222472">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Ah, don’t know why I didn’t grok the extension approach you suggested at first.  I like it!  That should work well.  I’ll give it a shot after we work out the resolution to <a href="https://github.com/mathieuprog/query_builder/issues/2" class="inline-onebox" rel="noopener nofollow ugc">Atom values in where args treated as schema fields · Issue #2 · mathieuprog/query_builder · GitHub</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="222472" 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/querybuilder-compose-ecto-queries-without-effort/27704/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-222472" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="222472"
                     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 #21"></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/27704/load_more?page=3">Load more posts (1 remaining)</a>
</div></template></turbo-stream>