coen.bakker
How to add fields of associated schema to fields of parent schema when querying with Ecto?
Context
I have several different types of books that are stored in my database. All books have some properties in common, but all book types have their own unique properties as well. Currently, I have a schema for the shared properties of books (books) and one for the non-shared properties of each type of book (type_a_books, type_b_books, etc).
schema "books" do
field :title, :string
...
field :type, :string # "TypeABook", "TypeBBook", etc.
has_many :publications, Publication
many_to_many :authors, Author, join_through: "authors_books"
has_one :type_a_book, TypeABook
has_one :type_b_book, TypeBBook
timestamps()
end
schema "type_a_books" do
field :story, :string
field :pictures, {:array, :string}
belongs_to :book, Book
end
schema "type_b_books" do
field :paths, {:array, :string}
field :pictures, {:array, :string}
field :videos, {:array, :string}
belongs_to :book, Book
end
I setup this model recently but I am now faced with the fact that I do not have a sufficient understanding of how to perform the needed queries. I have read the documentation of Ecto.Query, Ecto.Repo and Ecto.Schema, and learnt from several other sources.
Problem
I have not been able to figure out how to get the following data back from the database (N.B. the fields of TypeABook are joined to the fields of Book).
%{
id: "qwerty",
title: "A Purple Sky over Tokyo",
...
type: "type_a_book",
publications: [ #App.Publications.Publication<...> ],
authors: [ #App.Authors.Author<...> ],
story: "hello",
pictures: ["url", "url", "url"],
inserted_at: ~U[2023-02-20 13:06:54Z],
updated_at: ~U[2023-02-20 13:06:54Z]
}
The closest I got to this result is a simple query = from d in Draft, preload: [:authors, :publications, :type_a_book]. This, however, does not add the fields of TypeABook to the fields of Book. I have also tried to use join in assoc() and join in TypeABook, but I could never get it to work fully.
Feel free to also comment on my model or the general approach I am taking.
Most Liked
milangupta
Here is one approach that might work ?
And a previous forum post/pointer from @LostKobrakai - Data mapping and validation — Ecto v3.14.0
LostKobrakai
If your read and write side look rather different you can also go with different schemas fror them. Noone requires you do use the same ones.
milangupta
Glad it was helpful. It is a learning journey. I’m on my 3rd refactoring / re-design. What I love about the stack is that it is easy for a newbie to create something and then as you learn, you can really create some elegant stuff.
Your choices will really depend on the complexity of your application. There is still more to do with Ecto, but for simple/medium complexity stuff, it is great ! An example where I am still learning .. in designing the model with assocs (has_many/belongs_to etc.), the stuff that I still have to test thoroughly is around when a record is deleted (and the behavior of cascading deletes), specifically when a value is NULL. Postgres15’s addition of NULL not unique was a very very needed enhancement that was previously causing me a lot of workarounds etc.
Hope this helps ..
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









