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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>How do these libraries compare to Ash? Can Ash load nested map data into structs to and from JSON?</p>
<p><a class="mention" href="/u/zachdaniel" rel="nofollow">@zachdaniel</a></p>
<aside class="quote no-group quote-modified" data-username="venkatd" data-post="9" data-topic="70180" 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/venkatd/48/9419_2.png" class="avatar"> venkatd:</div>
<blockquote>
<p>I want to give a shoutout to the library Flint (<a href="https://github.com/acalejos/flint" rel="noopener nofollow ugc">GitHub - acalejos/flint: Declarative Ecto embedded schemas for data validation, coercion, and manipulation.</a>) which we have been using extensively in our app.</p>
<p>You can lean on Ecto to declare schemas and go to and from JSON.</p>
</blockquote>
</aside>
<aside class="quote no-group" data-username="mudasobwa" data-post="5" data-topic="70180" 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/mudasobwa/48/5298_2.png" class="avatar"> mudasobwa:</div>
<blockquote>
<p>You might want to take a look at <a href="https://hexdocs.pm/estructura" rel="noopener nofollow ugc"><code>estructura</code></a> library and specifically to <a href="https://hexdocs.pm/estructura/Estructura.User.html" rel="noopener nofollow ugc"><code>Estructura.User</code></a> example which is solving exactly the issues you’ve described:</p>
<ul>
<li>loading nested map data into structs</li>
<li>coercion of types (like ISO-8601 binary into <code>DateTime</code> struct)</li>
<li>input validation</li>
<li><em>and</em> generation of <code>StreamData</code> “instances” for property-based testing.</li>
</ul>
</blockquote>
</aside>
<aside class="quote no-group quote-modified" data-username="westmark" data-post="4" data-topic="70180" 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/westmark/48/29853_2.png" class="avatar"> westmark:</div>
<blockquote>
<p>Not a perfect solution to your issue, but I’ve been using <a href="https://hexdocs.pm/data_schema" rel="noopener nofollow ugc">data_schema v0.5.0 — Documentation</a> for quite some time now and very happy with it. We have extended it to include a lot more functionality to fit our business case better</p>
</blockquote>
</aside> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="360830" 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/de-serializing-json-documents-into-structs-just-include-struct-seemingly-not-quite/70180/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-360830" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="360830"
                     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="360836" data-post-id="360836">
  <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>Easily, yes. You can use the <code>:embedded</code> data layer to model an <code>Ash.Resource</code> that behaves like an <code>Ash.Type</code>.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule MyApp.Profile do
  use Ash.Resource, data_layer: :embedded

  attributes do
    attribute :bio, :string, allow_nil?: false
  end
end

# on `User` for example
attribute :profile, MyApp.Profile
</code></pre>
<p>The above has various interesting benefits like the ability to leverage policies, validations, custom actions on the resource to handle updating logic etc.</p>
<p>For simple map → struct validation, you can use the <code>:struct</code> type with the <code>:fields</code> constraint. I typically recommend using <code>Ash.Type.NewType</code> for this, which creates a new type based off of another type and constraints. For example:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule MyApp.Profile do
  destruct [:bio]

  use Ash.Type.NewType, subtype_of: :struct, constraints: [
    instance_of: __MODULE__,
    fields: [
      bio: [type: :string, allow_nil?: false, constraints: [min_length: 25]]
    ]
  ]
end
</code></pre>
<p>You can use custom types as field types, etc, allowing for pretty much anything you could want to do.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="360836" 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/de-serializing-json-documents-into-structs-just-include-struct-seemingly-not-quite/70180/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-360836" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="360836"
                     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>