And what exactly is the problem with that result - it already works …
#---
# Excerpted from "Programming Ecto",
# published by The Pragmatic Bookshelf.
# Copyrights apply to this code. It may not be used to create training material,
# courses, books, articles, and the like. Contact us if you are in doubt.
# We make no guarantees that this code is fit for any purpose.
# Visit http://www.pragmaticprogrammer.com/titles/wmecto for more book information.
#---
defmodule MusicDB.Album do
use Ecto.Schema
import Ecto.Changeset
alias MusicDB.{Artist, Track, Genre}
schema "albums" do
field(:title, :string)
timestamps()
belongs_to(:artist, Artist)
has_many(:tracks, Track)
many_to_many(:genres, Genre, join_through: "albums_genres")
end
def changeset(album, params) do
album
|> cast(params, [:title])
|> validate_required([:title])
end
end
iex(1)> alias MusicDB.{Repo,Album}
[MusicDB.Repo, MusicDB.Album]
iex(2)> import Ecto.Query
Ecto.Query
iex(3)> album_id = 2
2
iex(4)> assocs = [:tracks, :artist, :genres]
[:tracks, :artist, :genres]
iex(5)> assocs1 = Enum.take(assocs, 1)
[:tracks]
iex(6)> assocs2 = Enum.take(assocs, 2)
[:tracks, :artist]
iex(7)>
nil
iex(8)> query = from(a in Album, [
...(8)> preload: ^assocs1,
...(8)> where: a.id == ^album_id
...(8)> ])
#Ecto.Query<from a in MusicDB.Album, where: a.id == ^2, preload: [[:tracks]]>
iex(9)> Repo.all(query)
09:53:41.711 [debug] QUERY OK source="albums" db=2.4ms decode=1.8ms
SELECT a0."id", a0."title", a0."inserted_at", a0."updated_at", a0."artist_id" FROM "albums" AS a0 WHERE (a0."id" = $1) [2]
09:53:41.718 [debug] QUERY OK source="tracks" db=1.9ms
SELECT t0."id", t0."title", t0."duration", t0."index", t0."number_of_plays", t0."inserted_at", t0."updated_at", t0."album_id", t0."album_id" FROM "tracks" AS t0 WHERE (t0."album_id" = $1) ORDER BY t0."album_id" [2]
[
%MusicDB.Album{
__meta__: #Ecto.Schema.Metadata<:loaded, "albums">,
artist: #Ecto.Association.NotLoaded<association :artist is not loaded>,
artist_id: 1,
genres: #Ecto.Association.NotLoaded<association :genres is not loaded>,
id: 2,
inserted_at: ~N[2018-06-16 20:29:41.476625],
title: "Cookin' At The Plugged Nickel",
tracks: [
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 1061,
duration_string: nil,
id: 10,
index: 5,
inserted_at: ~N[2018-06-16 20:29:41.480612],
number_of_plays: 0,
title: "No Blues",
updated_at: ~N[2018-06-16 20:29:41.480618]
},
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 754,
duration_string: nil,
id: 9,
index: 4,
inserted_at: ~N[2018-06-16 20:29:41.480045],
number_of_plays: 0,
title: "Miles",
updated_at: ~N[2018-06-16 20:29:41.480051]
},
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 896,
duration_string: nil,
id: 8,
index: 3,
inserted_at: ~N[2018-06-16 20:29:41.479460],
number_of_plays: 0,
title: "Walkin'",
updated_at: ~N[2018-06-16 20:29:41.479465]
},
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 774,
duration_string: nil,
id: 7,
index: 2,
inserted_at: ~N[2018-06-16 20:29:41.478857],
number_of_plays: 0,
title: "Stella By Starlight",
updated_at: ~N[2018-06-16 20:29:41.478864]
},
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 1006,
duration_string: nil,
id: 6,
index: 1,
inserted_at: ~N[2018-06-16 20:29:41.478296],
number_of_plays: 0,
title: "If I Were A Bell",
updated_at: ~N[2018-06-16 20:29:41.478302]
}
],
updated_at: ~N[2018-06-16 20:29:41.476631]
}
]
iex(10)> query = from(a in Album, [
...(10)> preload: ^assocs2,
...(10)> where: a.id == ^album_id
...(10)> ])
#Ecto.Query<from a in MusicDB.Album, where: a.id == ^2,
preload: [[:tracks, :artist]]>
iex(11)> Repo.all(query)
09:53:41.728 [debug] QUERY OK source="albums" db=1.7ms
SELECT a0."id", a0."title", a0."inserted_at", a0."updated_at", a0."artist_id" FROM "albums" AS a0 WHERE (a0."id" = $1) [2]
09:53:41.734 [debug] QUERY OK source="tracks" db=2.0ms
SELECT t0."id", t0."title", t0."duration", t0."index", t0."number_of_plays", t0."inserted_at", t0."updated_at", t0."album_id", t0."album_id" FROM "tracks" AS t0 WHERE (t0."album_id" = $1) ORDER BY t0."album_id" [2]
09:53:41.734 [debug] QUERY OK source="artists" db=1.6ms
SELECT a0."id", a0."name", a0."birth_date", a0."death_date", a0."inserted_at", a0."updated_at", a0."id" FROM "artists" AS a0 WHERE (a0."id" = $1) [1]
[
%MusicDB.Album{
__meta__: #Ecto.Schema.Metadata<:loaded, "albums">,
artist: %MusicDB.Artist{
__meta__: #Ecto.Schema.Metadata<:loaded, "artists">,
albums: #Ecto.Association.NotLoaded<association :albums is not loaded>,
birth_date: nil,
death_date: nil,
id: 1,
inserted_at: ~N[2018-06-16 20:29:41.462600],
name: "Miles Davis",
tracks: #Ecto.Association.NotLoaded<association :tracks is not loaded>,
updated_at: ~N[2018-06-16 20:29:41.462606]
},
artist_id: 1,
genres: #Ecto.Association.NotLoaded<association :genres is not loaded>,
id: 2,
inserted_at: ~N[2018-06-16 20:29:41.476625],
title: "Cookin' At The Plugged Nickel",
tracks: [
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 1061,
duration_string: nil,
id: 10,
index: 5,
inserted_at: ~N[2018-06-16 20:29:41.480612],
number_of_plays: 0,
title: "No Blues",
updated_at: ~N[2018-06-16 20:29:41.480618]
},
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 754,
duration_string: nil,
id: 9,
index: 4,
inserted_at: ~N[2018-06-16 20:29:41.480045],
number_of_plays: 0,
title: "Miles",
updated_at: ~N[2018-06-16 20:29:41.480051]
},
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 896,
duration_string: nil,
id: 8,
index: 3,
inserted_at: ~N[2018-06-16 20:29:41.479460],
number_of_plays: 0,
title: "Walkin'",
updated_at: ~N[2018-06-16 20:29:41.479465]
},
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 774,
duration_string: nil,
id: 7,
index: 2,
inserted_at: ~N[2018-06-16 20:29:41.478857],
number_of_plays: 0,
title: "Stella By Starlight",
updated_at: ~N[2018-06-16 20:29:41.478864]
},
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 1006,
duration_string: nil,
id: 6,
index: 1,
inserted_at: ~N[2018-06-16 20:29:41.478296],
number_of_plays: 0,
title: "If I Were A Bell",
updated_at: ~N[2018-06-16 20:29:41.478302]
}
],
updated_at: ~N[2018-06-16 20:29:41.476631]
}
]
iex(12)> query = from(a in Album, [
...(12)> preload: ^assocs,
...(12)> where: a.id == ^album_id
...(12)> ])
#Ecto.Query<from a in MusicDB.Album, where: a.id == ^2,
preload: [[:tracks, :artist, :genres]]>
iex(13)> Repo.all(query)
09:53:41.738 [debug] QUERY OK source="albums" db=0.8ms
SELECT a0."id", a0."title", a0."inserted_at", a0."updated_at", a0."artist_id" FROM "albums" AS a0 WHERE (a0."id" = $1) [2]
09:53:41.741 [debug] QUERY OK source="artists" db=1.6ms
SELECT a0."id", a0."name", a0."birth_date", a0."death_date", a0."inserted_at", a0."updated_at", a0."id" FROM "artists" AS a0 WHERE (a0."id" = $1) [1]
09:53:41.741 [debug] QUERY OK source="tracks" db=1.8ms
SELECT t0."id", t0."title", t0."duration", t0."index", t0."number_of_plays", t0."inserted_at", t0."updated_at", t0."album_id", t0."album_id" FROM "tracks" AS t0 WHERE (t0."album_id" = $1) ORDER BY t0."album_id" [2]
09:53:41.744 [debug] QUERY OK source="genres" db=2.4ms
SELECT g0."id", g0."name", g0."wiki_tag", g0."inserted_at", g0."updated_at", a1."id" FROM "genres" AS g0 INNER JOIN "albums" AS a1 ON a1."id" = ANY($1) INNER JOIN "albums_genres" AS a2 ON a2."album_id" = a1."id" WHERE (a2."genre_id" = g0."id") ORDER BY a1."id" [[2]]
[
%MusicDB.Album{
__meta__: #Ecto.Schema.Metadata<:loaded, "albums">,
artist: %MusicDB.Artist{
__meta__: #Ecto.Schema.Metadata<:loaded, "artists">,
albums: #Ecto.Association.NotLoaded<association :albums is not loaded>,
birth_date: nil,
death_date: nil,
id: 1,
inserted_at: ~N[2018-06-16 20:29:41.462600],
name: "Miles Davis",
tracks: #Ecto.Association.NotLoaded<association :tracks is not loaded>,
updated_at: ~N[2018-06-16 20:29:41.462606]
},
artist_id: 1,
genres: [
%MusicDB.Genre{
__meta__: #Ecto.Schema.Metadata<:loaded, "genres">,
albums: #Ecto.Association.NotLoaded<association :albums is not loaded>,
id: 1,
inserted_at: ~N[2018-06-16 20:29:41.452406],
name: "jazz",
updated_at: ~N[2018-06-16 20:29:41.452415],
wiki_tag: "Jazz"
},
%MusicDB.Genre{
__meta__: #Ecto.Schema.Metadata<:loaded, "genres">,
albums: #Ecto.Association.NotLoaded<association :albums is not loaded>,
id: 2,
inserted_at: ~N[2018-06-16 20:29:41.460689],
name: "live",
updated_at: ~N[2018-06-16 20:29:41.460696],
wiki_tag: "Concert"
}
],
id: 2,
inserted_at: ~N[2018-06-16 20:29:41.476625],
title: "Cookin' At The Plugged Nickel",
tracks: [
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 1061,
duration_string: nil,
id: 10,
index: 5,
inserted_at: ~N[2018-06-16 20:29:41.480612],
number_of_plays: 0,
title: "No Blues",
updated_at: ~N[2018-06-16 20:29:41.480618]
},
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 754,
duration_string: nil,
id: 9,
index: 4,
inserted_at: ~N[2018-06-16 20:29:41.480045],
number_of_plays: 0,
title: "Miles",
updated_at: ~N[2018-06-16 20:29:41.480051]
},
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 896,
duration_string: nil,
id: 8,
index: 3,
inserted_at: ~N[2018-06-16 20:29:41.479460],
number_of_plays: 0,
title: "Walkin'",
updated_at: ~N[2018-06-16 20:29:41.479465]
},
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 774,
duration_string: nil,
id: 7,
index: 2,
inserted_at: ~N[2018-06-16 20:29:41.478857],
number_of_plays: 0,
title: "Stella By Starlight",
updated_at: ~N[2018-06-16 20:29:41.478864]
},
%MusicDB.Track{
__meta__: #Ecto.Schema.Metadata<:loaded, "tracks">,
album: #Ecto.Association.NotLoaded<association :album is not loaded>,
album_id: 2,
duration: 1006,
duration_string: nil,
id: 6,
index: 1,
inserted_at: ~N[2018-06-16 20:29:41.478296],
number_of_plays: 0,
title: "If I Were A Bell",
updated_at: ~N[2018-06-16 20:29:41.478302]
}
],
updated_at: ~N[2018-06-16 20:29:41.476631]
}
]
iex(14)>