Compare commits
4 Commits
18dde03b52
...
67a63e42c3
Author | SHA1 | Date |
---|---|---|
Ryan Rix | 67a63e42c3 | |
Ryan Rix | d9a5bc9d0e | |
Ryan Rix | 37d66cd533 | |
Ryan Rix | c7b783ce6c |
|
@ -11,9 +11,10 @@ The persistence model is a pretty simple Ecto model, it's got a single associati
|
|||
#+begin_src elixir :noweb-ref ecto-schema-and-fns
|
||||
use Ecto.Schema
|
||||
use Arc.Ecto.Schema
|
||||
use Arc.Ecto.Definition
|
||||
import Ecto.Changeset
|
||||
|
||||
schema "photo" do
|
||||
schema "photos" do
|
||||
belongs_to :thing, PokaIjo.Thing
|
||||
field :photo, PokaIjo.Photo.Type
|
||||
field :uuid, :string
|
||||
|
@ -24,8 +25,8 @@ end
|
|||
def changeset(photo, attrs) do
|
||||
photo
|
||||
|> Map.update(:uuid, Ecto.UUID.generate, fn val -> val || Ecto.UUID.generate end)
|
||||
|> cast(attrs, [:uuid])
|
||||
|> cast_attachments(attrs, [:photo])
|
||||
|> validate_required([:thing])
|
||||
end
|
||||
|
||||
@doc "attach a photo to the provided Thing"
|
||||
|
|
|
@ -105,8 +105,8 @@ defmodule PokaIjoWeb.Endpoint do
|
|||
|
||||
<<plug-configurations>>
|
||||
<<plug-session>>
|
||||
<<Plug_Static>>
|
||||
<<plug-uploads>>
|
||||
<<Plug-Static>>
|
||||
|
||||
plug PokaIjoWeb.Router
|
||||
end
|
||||
|
@ -114,7 +114,7 @@ end
|
|||
|
||||
Serve at "/" the static files from "priv/static" directory. Since we will use =phx.digest= we can =gzip= the assets.
|
||||
|
||||
#+begin_src elixir :noweb-ref Plug_Static
|
||||
#+begin_src elixir :noweb-ref Plug-Static
|
||||
plug Plug.Static,
|
||||
at: "/",
|
||||
from: :poka_ijo,
|
||||
|
|
|
@ -131,6 +131,14 @@ end
|
|||
<%= render_many @thing.contents, PokaIjoWeb.ThingView, "_card.html", conn: @conn %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= if Enum.count(@thing.photos) > 0 do %>
|
||||
<div class="grid-x small-up-2 medium-up-4">
|
||||
<%= for img <- @thing.photos do %>
|
||||
<%= img_tag PokaIjo.Photo.url({img.photo, img}, :thumb), class: "thumbnail cell" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-4 cell">
|
||||
|
@ -186,7 +194,7 @@ end
|
|||
|
||||
#+begin_src elixir :noweb-ref controller-new
|
||||
def new(conn, _params) do
|
||||
changeset = Thing.new()
|
||||
changeset = Thing.new(with_photo: true)
|
||||
|
||||
conn
|
||||
|> put_view(PokaIjoWeb.ThingView)
|
||||
|
@ -198,7 +206,7 @@ end
|
|||
|
||||
def insert(conn, %{"id" => id}) do
|
||||
container = Thing.get_by(id: id)
|
||||
changeset = Thing.new(%{"container_id" => container.id})
|
||||
changeset = Thing.new(%{"container_id" => container.id}, with_photo: true)
|
||||
|
||||
conn
|
||||
|> put_view(PokaIjoWeb.ThingView)
|
||||
|
@ -230,7 +238,7 @@ end
|
|||
<div class="callout warning">Warning: This does not have a parent object!</div>
|
||||
<% end %>
|
||||
|
||||
<%= form_for @changeset, route_thing(@conn, @changeset, assigns[:thing]), fn f -> %>
|
||||
<%= form_for @changeset, route_thing(@conn, @changeset, assigns[:thing]), [multipart: true], fn f -> %>
|
||||
<%= if @changeset.action do %>
|
||||
<div class="callout warning">Please check errors below!</div>
|
||||
<% end %>
|
||||
|
@ -259,6 +267,14 @@ end
|
|||
value: <%= number_input f, :value_cents, step: 'any', value: @changeset.data.value_cents / 100 %>
|
||||
<%= error_tag f, :value_cents %>
|
||||
</label>
|
||||
|
||||
<%= inputs_for f, :photos, fn imf -> %>
|
||||
<div class="form-group">
|
||||
<%= label imf, :photo %>
|
||||
<%= file_input imf, :photo %>
|
||||
<%= error_tag imf, :photo %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= submit "Submit", class: "button" %>
|
||||
<% end %>
|
||||
|
@ -308,7 +324,7 @@ def create(conn, params) do
|
|||
|> Thing.new()
|
||||
|> Thing.insert() do
|
||||
{:error, changeset} ->
|
||||
Logger.info("Changeset save failed: #{inspect(changeset.errors)}")
|
||||
Logger.info("Changeset save failed: #{inspect(changeset)}")
|
||||
|
||||
conn
|
||||
|> put_view(PokaIjoWeb.ThingView)
|
||||
|
@ -330,7 +346,7 @@ some simple tests for =dollar_string_to_cents/1=; this would be great to have qu
|
|||
#+begin_src elixir :tangle test/poka_ijo_web/controllers/thing_controller_test.exs
|
||||
defmodule WebControllersThingDollarConvertorTest do
|
||||
use PokaIjoWeb.ConnCase
|
||||
alias PokaIjo.{Repo, Thing}
|
||||
alias PokaIjo.{Repo, Thing, Photo}
|
||||
alias PokaIjoWeb.ThingController
|
||||
|
||||
|
||||
|
@ -434,7 +450,10 @@ end
|
|||
#+begin_src elixir :noweb-ref controller-edit
|
||||
def edit(conn, %{"id" => id}) do
|
||||
thing = Thing.get_by(id: id, preload: true)
|
||||
changeset = Thing.changeset(thing, %{})
|
||||
changeset = cond do
|
||||
Enum.count(thing.photos) > 0 -> Thing.changeset(thing, %{})
|
||||
Enum.count(thing.photos) == 0 -> Thing.changeset(thing, %{photos: [%{}]})
|
||||
end
|
||||
|
||||
conn
|
||||
|> put_view(PokaIjoWeb.ThingView)
|
||||
|
@ -454,7 +473,7 @@ def update(conn, %{"id" => id} = params) do
|
|||
|
||||
case Thing.update(changeset) do
|
||||
{:error, changeset} ->
|
||||
Logger.info("Changeset save failed: #{inspect(changeset.errors)}")
|
||||
Logger.info("Changeset save failed: #{inspect(changeset)}")
|
||||
|
||||
conn
|
||||
|> put_view(PokaIjoWeb.ThingView)
|
||||
|
@ -701,7 +720,7 @@ defmodule PokaIjoWeb.ThingController do
|
|||
use PokaIjoWeb, :controller
|
||||
|
||||
require Logger
|
||||
alias PokaIjo.Thing
|
||||
alias PokaIjo.{Repo, Photo, Thing}
|
||||
|
||||
<<controller-index>>
|
||||
<<controller-show>>
|
||||
|
|
13
things.org
13
things.org
|
@ -7,7 +7,7 @@ This data model is pretty simple, Poka Ijo is made of Things. A =Thing= represen
|
|||
defmodule PokaIjo.Thing do
|
||||
use Ecto.Schema
|
||||
require Logger
|
||||
alias PokaIjo.{Thing, Repo}
|
||||
alias PokaIjo.{Thing, Repo, Photo}
|
||||
|
||||
<<schema>>
|
||||
|
||||
|
@ -87,6 +87,10 @@ These functions aid in the creation and update of Things.
|
|||
def new params do
|
||||
Thing.changeset(%Thing{}, params)
|
||||
end
|
||||
|
||||
def new params, with_photo: true do
|
||||
Thing.changeset(%Thing{photos: [%Photo{}]})
|
||||
end
|
||||
|
||||
def new do
|
||||
new %{}
|
||||
|
@ -95,13 +99,14 @@ These functions aid in the creation and update of Things.
|
|||
|
||||
- =PokaIjo.Thing.changeset/2= returns a changeset based on the thing in arg 1
|
||||
#+begin_src elixir :noweb-ref thing-changeset
|
||||
def changeset thing, params do
|
||||
def changeset thing, params \\ %{} do
|
||||
required_keys = [:name, :description]
|
||||
all_keys = required_keys ++ [:container_id, :value_cents, :url]
|
||||
|
||||
thing
|
||||
|> cast(params, all_keys)
|
||||
|> cast_assoc(:container)
|
||||
|> cast_assoc(:photos)
|
||||
|> validate_required(required_keys)
|
||||
|> validate_change(:container_id, fn :container_id, container_id ->
|
||||
cond do
|
||||
|
@ -145,7 +150,7 @@ I have some simple "getters" now:
|
|||
end
|
||||
|
||||
def all(preload: true) do
|
||||
all() |> Repo.preload([:container, :contents])
|
||||
all() |> Repo.preload([:container, :contents, :photos])
|
||||
end
|
||||
#+end_src
|
||||
|
||||
|
@ -165,7 +170,7 @@ I have some simple "getters" now:
|
|||
|
||||
true ->
|
||||
Repo.get_by(Thing, fparams)
|
||||
|> Repo.preload([:contents, :container])
|
||||
|> Repo.preload([:contents, :container, :photos])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue