defmodule InventoryCore.ProductForm do
import Ecto.Changeset
use Ecto.Schema
alias InventoryCore.Product
alias InventoryCore.SpreeProduct
alias InventoryCore.EbayProduct
embedded_schema do
field :title, :string
field :description, :string
field :price, :decimal
field :spree_taxon_ids, {:array, :integer}
field :spree_properties, {:array, :map}
field :ebay_category_id, :integer
field :ebay_secondary_category_id, :integer
field :ebay_sub_title, :string
field :ebay_specifics, {:array, :map}
end
@fields ~w(title description price spree_taxon_ids spree_properties ebay_category_id ebay_secondary_category_id ebay_sub_title ebay_specifics)a
@required_fields ~w(title description price spree_taxon_ids ebay_category_id)a
@max_title_length 80
@max_ebay_sub_title_length 55
def build(product, params) do
InventoryCore.ProductForm
|> struct(product |> serialize)
|> cast(params, @fields)
|> validate_required(@required_fields)
|> validate_length(:title, max: @max_title_length)
|> validate_length(:ebay_sub_title, max: @max_ebay_sub_title_length)
end
def serialize(%Product{ebay_product: %EbayProduct{}, spree_product: %SpreeProduct{}} = product) do
%{
id: product.id,
title: product.title,
description: product.description,
price: product.price,
spree_taxon_ids: product.spree_product.taxon_ids,
spree_properties: product.spree_product.properties,
ebay_category_id: product.ebay_product.category_id,
ebay_secondary_category_id: product.ebay_product.secondary_category_id,
ebay_sub_title: product.ebay_product.sub_title,
ebay_specifics: product.ebay_product.specifics
}
end
def serialize(_), do: %{}
def attributes(form) do
form.data
|> Map.drop([:__struct__])
|> Map.merge(form.changes)
end
end
Usage (CRU[D]):
- New:
form = ProductForm.build(%Product{spree_product: %SpreeProduct{}, , ebay_product: %EbayProduct{})
- Edit:
product =
Product
|> Repo.get(id)
|> Repo.preload(:ebay_product)
|> Repo.preload(:spree_product)
form = ProductForm.build(product, %{})
- Create\Update:
form = ProductForm.build(product, product_params) # product_params - params from request
form.valid? # true\false
attributes = ProductForm.attributes(form)