Skip to content

Commit

Permalink
Add a nested form with an embedded schema
Browse files Browse the repository at this point in the history
  • Loading branch information
andreaseriksson committed Jun 1, 2021
1 parent bb47213 commit 2f50ad0
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 4 deletions.
17 changes: 17 additions & 0 deletions lib/tutorial/shop/data.ex
@@ -0,0 +1,17 @@
defmodule Tutorial.Shop.Data do
use Ecto.Schema
import Ecto.Changeset

@primary_key false
embedded_schema do
field :size, :string
field :color, :string
end

@doc false
def changeset(option, attrs) do
option
|> cast(attrs, [:size, :color])
|> validate_required([])
end
end
5 changes: 5 additions & 0 deletions lib/tutorial/shop/product.ex
Expand Up @@ -2,12 +2,16 @@ defmodule Tutorial.Shop.Product do
use Ecto.Schema
import Ecto.Changeset

alias Tutorial.Shop.Data # <-- ADD THIS LINE

@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "shop_products" do
field :archived_at, :naive_datetime
field :name, :string

embeds_one :data, Data, on_replace: :update # <-- ADD THIS LINE

timestamps()
end

Expand All @@ -16,5 +20,6 @@ defmodule Tutorial.Shop.Product do
product
|> cast(attrs, [:name, :archived_at])
|> validate_required([:name])
|> cast_embed(:data) # <-- ADD THIS LINE
end
end
21 changes: 18 additions & 3 deletions lib/tutorial_web/live/admin/product_live/form_component.html.leex
Expand Up @@ -6,9 +6,24 @@
phx_change: "validate",
phx_submit: "save" %>

<%= label f, :name %>
<%= text_input f, :name, class: "form-control" %>
<%= error_tag f, :name %>
<div class="mb-4">
<%= label f, :name %>
<%= text_input f, :name, class: "form-control" %>
<%= error_tag f, :name %>
</div>

<%= inputs_for f, :data, fn ff -> %>
<div class="mb-4">
<%= label ff, :size %>
<%= text_input ff, :size, class: "form-control" %>
<%= error_tag ff, :size %>
</div>
<div class="mb-4">
<%= label ff, :color %>
<%= text_input ff, :color, class: "form-control" %>
<%= error_tag ff, :color %>
</div>
<% end %>

<div class="mt-6">
<%= submit "Save", class: "btn btn-primary", phx_disable_with: "Saving..." %>
Expand Down
@@ -0,0 +1,9 @@
defmodule Tutorial.Repo.Migrations.AddDataColumnToProducts do
use Ecto.Migration

def change do
alter table(:shop_products) do
add :data, :map, default: %{}, null: false
end
end
end
15 changes: 14 additions & 1 deletion test/tutorial/shop_test.exs
Expand Up @@ -16,7 +16,7 @@ defmodule Tutorial.ShopTest do
|> Enum.into(@valid_attrs)
|> Shop.create_product()

product
Shop.get_product!(product.id)
end

test "list_shop_products/0 returns all shop_products" do
Expand Down Expand Up @@ -62,5 +62,18 @@ defmodule Tutorial.ShopTest do
product = product_fixture()
assert %Ecto.Changeset{} = Shop.change_product(product)
end

test "create_product/1 with data attributes casts and updates embedded data" do
valid_attrs = Map.put(@valid_attrs, :data, %{size: "L", color: "green"})

assert {:ok, %Product{} = product} = Shop.create_product(valid_attrs)
assert product.data.size == "L"
assert product.data.color == "green"

update_attrs = Map.put(@valid_attrs, :data, %{size: "M", color: "red"})
assert {:ok, %Product{} = product} = Shop.update_product(product, update_attrs)
assert product.data.size == "M"
assert product.data.color == "red"
end
end
end

0 comments on commit 2f50ad0

Please sign in to comment.