Simplify data model
Artists can be embedded inside records - given the projected size of the dataset (a few 1000s in the worst case) relationships can be built in memory without the need to be denormalized into separate tables.
This commit is contained in:
@@ -37,15 +37,7 @@ defmodule MusicLibrary.Records do
|
||||
** (Ecto.NoResultsError)
|
||||
|
||||
"""
|
||||
def get_record!(id) do
|
||||
q =
|
||||
from r in Record,
|
||||
left_join: a in assoc(r, :artists),
|
||||
preload: [artists: a],
|
||||
where: r.id == ^id
|
||||
|
||||
Repo.one!(q)
|
||||
end
|
||||
def get_record!(id), do: Repo.get!(Record, id)
|
||||
|
||||
@doc """
|
||||
Creates a record.
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
defmodule MusicLibrary.Records.Artist do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
|
||||
alias MusicLibrary.{Records.ArtistRecord, Records.Record}
|
||||
|
||||
@primary_key {:id, :binary_id, autogenerate: true}
|
||||
@foreign_key_type :binary_id
|
||||
schema "artists" do
|
||||
field :name, :string
|
||||
field :image, :string
|
||||
field :musicbrainz_id, Ecto.UUID
|
||||
|
||||
many_to_many :records, Record, join_through: ArtistRecord
|
||||
|
||||
timestamps(type: :utc_datetime)
|
||||
end
|
||||
|
||||
@doc false
|
||||
def changeset(artist, attrs) do
|
||||
artist
|
||||
|> cast(attrs, [:name, :musicbrainz_id, :image])
|
||||
|> validate_required([:name, :musicbrainz_id, :image])
|
||||
end
|
||||
end
|
||||
@@ -1,20 +0,0 @@
|
||||
defmodule MusicLibrary.Records.ArtistRecord do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
|
||||
@primary_key {:id, :binary_id, autogenerate: true}
|
||||
@foreign_key_type :binary_id
|
||||
schema "artists_records" do
|
||||
field :artist_id, :binary_id
|
||||
field :record_id, :binary_id
|
||||
|
||||
timestamps(type: :utc_datetime)
|
||||
end
|
||||
|
||||
@doc false
|
||||
def changeset(artist_record, attrs) do
|
||||
artist_record
|
||||
|> cast(attrs, [])
|
||||
|> validate_required([])
|
||||
end
|
||||
end
|
||||
@@ -2,8 +2,6 @@ defmodule MusicLibrary.Records.Record do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
|
||||
alias MusicLibrary.{Records.Artist, Records.ArtistRecord}
|
||||
|
||||
@primary_key {:id, :binary_id, autogenerate: true}
|
||||
@foreign_key_type :binary_id
|
||||
schema "records" do
|
||||
@@ -14,7 +12,10 @@ defmodule MusicLibrary.Records.Record do
|
||||
field :musicbrainz_id, Ecto.UUID
|
||||
field :genres, {:array, :string}
|
||||
|
||||
many_to_many :artists, Artist, join_through: ArtistRecord
|
||||
embeds_many :artists, Artist do
|
||||
field :name, :string
|
||||
field :musicbrainz_id, Ecto.UUID
|
||||
end
|
||||
|
||||
timestamps(type: :utc_datetime)
|
||||
end
|
||||
@@ -25,4 +26,10 @@ defmodule MusicLibrary.Records.Record do
|
||||
|> cast(attrs, [:type, :title, :musicbrainz_id, :year, :genres, :image])
|
||||
|> validate_required([:type, :title, :musicbrainz_id, :year, :genres, :image])
|
||||
end
|
||||
|
||||
def add_artists(record, artists_attrs) do
|
||||
record
|
||||
|> change()
|
||||
|> put_embed(:artists, artists_attrs)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user