Ich möchte ein Modul aus kleineren Modulen zusammensetzen.Code-Duplizierung in Elixir und Ecto
Dies ist ein Modul ich jetzt haben:
defmodule Api.Product do
use Ecto.Schema
import Ecto.Changeset
import Api.Repo
import Ecto.Query
@derive {Poison.Encoder, only: [:name, :brand, :description, :image, :rating, :number_of_votes]}
schema "products" do
field :name, :string
field :brand, :string
field :description, :string
field :image, :string
field :rating, :integer
field :number_of_votes, :integer
field :not_vegan_count, :integer
end
def changeset(product, params \\ %{}) do
product
|> cast(params, [:name, :brand, :description, :image, :rating, :number_of_votes, :not_vegan_count])
|> validate_required([:name, :description, :brand])
|> unique_constraint(:brand, name: :unique_product)
end
def delete_all_from_products do
from(Api.Product) |> delete_all
end
def insert_product(conn, product) do
changeset = Api.Product.changeset(%Api.Product{}, product)
errors = changeset.errors
valid = changeset.valid?
case insert(changeset) do
{:ok, product} ->
{:success, product}
{:error, changeset} ->
{:error, changeset}
end
end
def get_product_by_name_and_brand(name, brand) do
Api.Product |> Ecto.Query.where(name: ^name) |> Ecto.Query.where(brand: ^brand) |> all
end
def get_products do
Api.Product |> all
end
end
Aber ich will andere verschiedene Dinge haben, als Product
, die alle die meisten die gleichen Felder wie Product
Ausnahme brand
haben. Daher ist es am besten, ein Modul zu erstellen, das alle Felder außer brand
enthält und dann alle Module, die diese Felder enthalten, dieses Modul als Feld haben?
Hier ist mein Modul, das alle Module enthalten würde:
defmodule Api.VeganThing do
use Ecto.Schema
import Ecto.Changeset
import Api.Repo
import Ecto.Query
@derive {Poison.Encoder, only: [:name, :description, :image, :rating, :number_of_votes]}
schema "vegan_things" do
field :name, :string
field :description, :string
field :image, :string
field :rating, :integer
field :number_of_votes, :integer
field :not_vegan_count, :integer
end
end
Es wird für vegan_things
keine Datenbanktabelle sein. Aber einige verschiedene Module, die Datenbanktabellen haben, enthalten eine vegan_thing
.
Ist dies ein guter Weg, um die Code-Duplizierung zu vermeiden, jedes Feld in jedem Modul in Elixir neu zu schreiben?
Hier ist meine aktuelle changeset:
defmodule Api.Repo.Migrations.CreateProducts do
use Ecto.Migration
def change do
create table(:products) do
add :name, :string
add :brand, :string
add :description, :string
add :image, :string
add :rating, :integer
add :number_of_votes, :integer
add :not_vegan_count, :integer
end
create unique_index(:products, [:name, :brand], name: :unique_product)
end
end
So die Einzigartigkeit auf einem Feld Ich bin stützen, die in vegan_thing
und ein Feld sein würde, die in product
nur. Kann ich so etwas tun?
defmodule Api.Repo.Migrations.CreateProducts do
use Ecto.Migration
def change do
create table(:products) do
add :name, :string
add :vegan_thing, :vegan_thing
end
create unique_index(:products, [:vegan_thing.name, :brand], name: :unique_product)
end
end
Oder muss ich in product
direkt das name
Feld setzen? anstelle von vegan_thing
in der Lage sein, es als eine einzigartige Einschränkung zu verwenden?
Wie ['Ecto.Schema.embedded_schema/1'] (https://hexdocs.pm/ecto/Ecto.Schema.html#embedded_schema/1)? – mudasobwa