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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Then there’s no time to refactor the database schema. I always encourage people to not half-ass the database design. Do it properly from the get go. It’s like in sports. If you lack the fundamentals, it’s very hard to compensate 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="386602" 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/how-do-you-model-different-types-with-totally-different-fields-in-ecto/74944/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-386602" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="386602"
                     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="386615" data-post-id="386615">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>It depends Ash can’t do everything and you will eventually have to write SQL, I never worked on a project that never had to do that at somepoint. I’m looking forward to tackle migrations next as thats when are going to take a fresh look at what a Ecto.Schema or Ash.Resource is in the world of a relational database is, as we can do things they have a harder time doing.</p>
<p>Most DSLs ends up being tightly coupled. In SQL we flip it upside down. You have access to the whole row when transforming in Elixir and SQL queries stays in the database.</p>
<p>Although we still got some ways to reduce verbosity, but hopefully thats where the community will chime in with better ideas then I have, I’m more of a lets get the engineering fundamentals right, then everything else becomes easy to build on top of.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="386615" 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/how-do-you-model-different-types-with-totally-different-fields-in-ecto/74944/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-386615" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="386615"
                     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="386626" data-post-id="386626">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I definitely agree with the sentiment but I’d be careful not to confuse design w/ implementation. The design decision was sub-typing, single table vs many tables is implementation. “No time to refactor” holds true in the other direction; if you over complicate things, you’ll be stuck with it. That’s why I said “when starting new projects”, alluding to not knowing exactly what’s necessary. May end up with only 3 sub-type specific columns and no sub-type specific relations. I don’t want to hijack the thread though as this is off-topic from the original post because I agree with what you said</p>
<p>Edit: some clarifications</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="386626" 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/how-do-you-model-different-types-with-totally-different-fields-in-ecto/74944/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-386626" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="386626"
                     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="386633" data-post-id="386633">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="onebox allowlistedgeneric" data-onebox-src="https://ecto.hexdocs.pm/polymorphic-associations-with-many-to-many.html">
  <header class="source">

      <a href="https://ecto.hexdocs.pm/polymorphic-associations-with-many-to-many.html" target="_blank" rel="noopener nofollow ugc">ecto.hexdocs.pm</a>
  </header>

  <article class="onebox-body">
    

<h3><a href="https://ecto.hexdocs.pm/polymorphic-associations-with-many-to-many.html" target="_blank" rel="noopener nofollow ugc">Polymorphic associations with many to many — Ecto v3.14.0</a></h3>



  </article>

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

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

<p>This is one way I’ve tried that seems convenient in ecto. In the todo list example, it would look something like this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  schema "items" do
    field :description, :string
    # join with either a join schema or just a raw join table
    many_to_many :lists, Todo.List, join_through: Todo.ListItem
    many_to_many :projects, Todo.Project, join_through: "projects_items"

    field :itemable, :map, virtual: true

    timestamps(type: :utc_datetime)
  end

  schema "lists" do
    field :title, :string
    many_to_many :items, Todo.Items.Item, join_through: Todo.ListItem

    timestamps(type: :utc_datetime)
  end

  schema "projects" do
    field :name, :string
    many_to_many :items, Todo.Items.Item, join_through: "projects_items"

    timestamps(type: :utc_datetime)
  end
</code></pre>
<p>In a page that lists all items, I do this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  # context functions
  def get_items_with_itemable do
    Item
    |&gt; Repo.all()
    |&gt; Repo.preload([:lists, :projects])
    |&gt; Enum.map(&amp;add_itemable/1)
  end

  defp add_itemable(nil), do: nil

  defp add_itemable(%Item{} = item) do
    Map.put(item, :itemable, get_itemable(item))
  end

  defp get_itemable(%Item{} = item) do
    list = List.first(item.lists)
    project = List.first(item.projects)

    list || project
  end

  # live view
  def render(assigns) do
    ~H"""
    &lt;Layouts.app flash={@flash}&gt;
      &lt;ul&gt;
        &lt;li :for={i &lt;- @items}&gt;
          {"#{display_itemable(i.itemable)} - #{i.description}"}
        &lt;/li&gt;
      &lt;/ul&gt;
    &lt;/Layouts.app&gt;
    """
  end

  defp display_itemable(%Todo.List{title: title}), do: title
  defp display_itemable(%Todo.Project{name: name}), do: name
  defp display_itemable(_), do: ""
</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="386633" 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/how-do-you-model-different-types-with-totally-different-fields-in-ecto/74944/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-386633" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="386633"
                     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="386686" data-post-id="386686">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="PaleWatcher" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  PaleWatcher
                    <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>Thanks everyone for the responses!</p>
<hr>
<p><strong>Context / why I asked</strong></p>
<p>While learning Ecto / Phoenix / LiveView, I ran into this modeling dilemma and was trying to understand the different layers at the same time.</p>
<p>Before the full mental model was really in place, I was jumping between different layers due to the learning process.</p>
<hr>
<p><strong>Why I didn’t immediately propose my own solution</strong></p>
<p>I also explored the direction linked by LostKobrakai earlier (separate types, separate structures), but what held me back was:</p>
<ul>
<li>at the database level, I modeled this using composite-key / multi-field identity approaches</li>
<li>in Ecto, this is not really supported in a native or idiomatic way</li>
<li>so it wasn’t clear to me whether this approach is actually considered idiomatic in an Ecto context</li>
</ul>
<hr>
<p><strong>Ecto vs data modeling</strong></p>
<p>What I found interesting is that Ecto + LiveView changesets work really well together, especially for dynamic forms.</p>
<p>If I completely drop Ecto, I don’t just lose an ORM, but also a very useful validation + UI integration layer.</p>
<p>At the same time, it became increasingly clear to me that the database model and the Ecto schema are not the same thing.</p>
<p>At the database level, you can have a perfectly valid relational model (e.g. composite-key / subtype-style structure), which Ecto doesn’t necessarily map in a natural way.</p>
<hr>
<p><strong>Concrete example (simplified)</strong></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">schema "items" do
  field :type, Ecto.Enum, values: [:item_one, :item_two]

 has_one :item_one
 has_one :item_two

end
</code></pre>
<p>And the more specific schemas:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">@primary_key {:id, :id, autogenerate: false}
schema "item_one" do
 field :type, Ecto.Enum, values: [:item_one], default: :item_one

 belongs_to :item, Item
end
</code></pre>
<pre data-code-wrap="elixir"><code class="lang-elixir">@primary_key {:id, :id, autogenerate: false}
schema "item_two" do
 field :type, Ecto.Enum, values: [:item_two], default: :item_two

 belongs_to :item, Item
end
</code></pre>
<pre data-code-wrap="elixir"><code class="lang-elixir"></code></pre>
<p><a class="mention" href="/u/sodapopcan" rel="nofollow">@sodapopcan</a></p>
<p>This is a really interesting approach — I find the idea of abstracting the association into a single “slot” quite compelling, especially as the number of possible underlying tables grows.</p>
<p>In my case the domain already tends toward multiple item types, so avoiding a growing number of empty or optional <code>has_one</code> associations is exactly the kind of problem I was running into.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="386686" 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/how-do-you-model-different-types-with-totally-different-fields-in-ecto/74944/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-386686" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="386686"
                     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="387067" data-post-id="387067">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Schultzer" data-post="13" data-topic="74944">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/schultzer/48/4339_2.png" class="avatar"> Schultzer:</div>
<blockquote>
<p>I’m looking forward to tackle migrations next as thats when are going to take a fresh look at what a Ecto.Schema or Ash.Resource is in the world of a relational database is, as we can do things they have a harder time doing.</p>
</blockquote>
</aside>
<p>Curious to know what kind of thing you have in mind here.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="387067" 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/how-do-you-model-different-types-with-totally-different-fields-in-ecto/74944/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-387067" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="387067"
                     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="388123" data-post-id="388123">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Most of my thoughts has been that we have always done things where we try to create a DSL to support multiple datastore, instead of embracing the language that already is there. SQL can be first class, adaptable and specialized at the same time. Elixir is uniquely positioned as it is extensible and you can implement foreign language integration with ease, something I’ve never seen done in other languages, which might be why we’ve been dealing with ORMs for over thirty years. Maybe it’s time to think differently?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="388123" 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/how-do-you-model-different-types-with-totally-different-fields-in-ecto/74944/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-388123" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="388123"
                     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="388137" data-post-id="388137">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Ash isn’t strictly speaking an ORM although it does quack like that duck for most applications using it <img src="https://forum.elixirforum.com/images/emoji/apple/laughing.png?v=15" title=":laughing:" class="emoji" alt=":laughing:" loading="lazy" width="20" height="20"></p>
<p>If all we’re talking about is running queries and getting their results in Elixir structs and that’s the most that you want out of a given tool then its a different discussion, but with Ash we’re much more concerned with generalized modeling problems, or application building primitives and running SQL queries is just “one way” you might do that.</p>
<p>Some examples:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">policies do
  policy action_type(:read) do
    authorize_if expr(public == true)
  end
end
</code></pre>
<p>If you had a policy like this, Ash will lower it into SQL when running the query:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Ash.read!(Resource)
#=&gt; SELECT * FROM "table" WHERE public = TRUE
</code></pre>
<p>But you can also leverage that policy for a lot more things. For example, you can ask for a policy flow chart to hand over for a security audit. Or you can evaluate the policy in memory:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Ash.can?(Resource, :read, %User{}, 
  data: %Resource{public: false}, 
  reuse_values?: true # use the values we have in memory
)
</code></pre>
<p>In which case Ash will run the given expression <em>in memory</em>.</p>
<p>Or, for example, the following validation:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">update :increment_score do
  argument :amount, :integer, default: 1

  change atomic_update(:score, expr(score + ^arg(:amount)))
  validate compare(:score, less_than: 100)
end
</code></pre>
<p>When you run this action, you will get SQL like this:</p>
<pre data-code-wrap="sql"><code class="lang-sql">UPDATE things 
SET
  id = CASE WHEN
    score + {amount} &gt; 100 THEN
      ash_raise_error(...) -- We raise an equivalent error
    ELSE
      id
    END
  score = score + {amount}
WHERE id = {id}
AND public = true -- policies embedded into queries
</code></pre>
<p>Ash is <em>far</em> more than an ORM these are just some examples of that (and likely not really the best ones).<br>
In every non-trivial application I’ve ever worked with ultimately your business logic crosses multiple systems, or multiple queries etc. that must be operated on in concert.</p>
<p>If composition is limited to statements to a data layer, you’re constrained by the capabilities of that data layer. Likewise what Ash brings to the table primarily has to do with a whole suite of intelligent composition that may result in many queries, or even zero queries when running actions.</p>
<hr>
<p>Even with that in mind my question was more about what concrete limitations you see in Ash that could be otherwise addressed by something more SQL-native as it could easily represent gaps in Ash. With that said, Ash isn’t intended to replace all interaction with a database, it’s about your domain logic. This is perfectly valid Ash code:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">action :list_users, {:array, :struct} do
  constraints items: [instance_of: __MODULE__]

  run fn input, _ -&gt; 
    result =
      ~SQL[from users select *]
      |&gt; SQL.map(fn row -&gt; struct(User, row) end)
      |&gt; Enum.to_list()
  
    {:ok, result} 
  end
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="388137" 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/how-do-you-model-different-types-with-totally-different-fields-in-ecto/74944/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-388137" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="388137"
                     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="388138" data-post-id="388138">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>No doubt that Ash is more then an ORM, the reason why I mentioned Ash was mostly due to the work around automated migration which Ecto is lacking.</p>
<p>The biggest issues I find with traditional ORMs and DSLs in general is lack of precision. I believe that the abstraction is done at the wrong level, which ends up causing more complexity and issues overtime, as the abstraction leaks.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="388138" 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/how-do-you-model-different-types-with-totally-different-fields-in-ecto/74944/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-388138" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="388138"
                     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="388145" data-post-id="388145">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>To me it’s ultimately about progressive complexity adoption. i.e “precision” is just one of many attributes of any given implementation of a solution to a problem, one that doesn’t always have to be at 10. i.e if you have this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule SomeResource do
  ...

  actions do
    read :read
  end
end
</code></pre>
<p>You can <code>Ash.read!(SomeResource)</code>, but there is no control in Ash anywhere for the order in which you select fields. Technically something out of your control that would make a more specific SQL query in any given case, but no one has ever asked for that feature because its never mattered. My general pattern is to build for the most common cases where the thing or things you are doing can be done hundreds of different ways, but none of them meaningfully better or worse than the others. <em>then</em> if you realize “this SQL query performs bad!” you get escape hatches to then opt into the more specific version of it (like the action I showed above).</p>
<p>On the Ecto lacking migration generation feature, I think it’s possible that it could make sense at that level, but personally I feel that is the job of something that sits higher up in the stack like Ash. Ash benefits from a wonderfully open ecosystem supported by ecto/phoenix (and also packages like yours!) but the more opinionated they get, the harder it actually gets for me to build a high quality abstraction on top of them. i.e Ash does magic to track custom statements, custom identities, unique indexes etc. none of which are modeled by Ecto schemas (which is why Jose didn’t add it if I recall that conversation correctly).</p>
<p>Regardless, I’m interested in other ways of doing things especially if they surface unique options that can’t be provided by Ash or unique benefits. One major one of SQL that I’m sure Ash is nowhere near on is things like individual query performance. We have a bunch of performance enhancements for applications “in general” that are mostly transparent to users (i.e the automatic translation of “get and update” style queries to single “update” queries whenever possible. But I’d be willing to bet a SQL query is faster than an Ash action that gets to a SQL query by a factor of like…100 lol. I’ll optimize the internals pretty heavily after 4.0 but even still it will probably never even be close.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="388145" 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/how-do-you-model-different-types-with-totally-different-fields-in-ecto/74944/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-388145" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="388145"
                     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 #20"></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/74944/load_more?page=3">Load more posts (2 remaining)</a>
</div></template></turbo-stream>