Diamond Application Development Crafting Solutions with Precision
Introduction to Elixir and Phoenix.pdf
1. Introduction to Elixir and
Phoenix
Created by Ridwan Fadjar Septian,
At SenseHealth B.V.
Bandung, 26th September 2018
2. Disclaimer
- I am just curious about Elixir and Phoenix Web Framework for personal usage only
- Currently I don’t have an experience using Elixir in production
- I bought Elixir and Phoenix course on Udemy for my hobby
- Alam embrace me to learn Elixir and set up a sharing session
12. Conditional
iex> if String.valid?("Hello") do
...> "Valid string!"
...> else
...> "Invalid string."
...> end
"Valid string!"
iex> if "a string value" do
...> "Truthy"
...> end
"Truthy"
14. Conditional
iex> case {:ok, "Hello World"} do
...> {:ok, result} -> result
...> {:error} -> "Uh oh!"
...> _ -> "Catch all"
...> end
"Hello World"
15. Conditional
iex> cond do
...> 2 + 2 == 5 ->
...> "This will not be true"
...> 2 * 2 == 3 ->
...> "Nor this"
...> 1 + 1 == 2 ->
...> "But this will"
...> end
"But this will"
16. Recursion
defmodule Loop do
def print_multiple_times
(msg, n) when n <= 1 do
IO.puts msg
end
def print_multiple_times
(msg, n) do
IO.puts msg
print_multiple_times
(msg, n - 1)
end
end
Loop.print_multiple_times
("Hello", 10)
17. Function
iex> sum = fn (a, b) -> a + b end
iex> sum.(2, 3)
5
iex> sum = &(&1 + &2)
iex> sum.(2, 3)
5
18. Function and Module
defmodule Greeter do
def hello(name) do
"Hello, " <> name
end
end
iex> Greeter.hello("Sean")
"Hello, Sean"
19. Function and Module
defmodule Greeter2 do
def hello(), do: "Hello, anonymous person!" # hello/0
def hello(name), do: "Hello, " <> name # hello/1
def hello(name1, name2), do: "Hello, #{name1} and #{name2}"
# hello/2
end
iex> Greeter2.hello()
"Hello, anonymous person!"
iex> Greeter2.hello("Fred")
"Hello, Fred"
iex> Greeter2.hello("Fred", "Jane")
"Hello, Fred and Jane"
25. Models
schema "gps_tracking" do
field :application_id, Ecto.UUID
field :created_at, :utc_datetime
field :latitude, :string
field :longitude, :string
field :user_id, Ecto.UUID
timestamps()
end
@doc false
def changeset(gps_tracking, attrs) do
gps_tracking
|> cast(attrs, [:application_id, :user_id, :latitude, :longitude, :created_at])
|> validate_required([:application_id, :user_id, :latitude, :longitude, :created_at])
end
26. Repo
def list_gps_tracking do
Repo.all(GPSTracking)
end
def get_gps_tracking!(id), do: Repo.get!(GPSTracking, id)
def create_gps_tracking(attrs %{}) do
%GPSTracking{}
|> GPSTracking.changeset(attrs)
|> Repo.insert()
end
def update_gps_tracking(%GPSTracking{} = gps_tracking, attrs) do
gps_tracking
|> GPSTracking.changeset(attrs)
|> Repo.update()
end
def delete_gps_tracking(%GPSTracking{} = gps_tracking) do
Repo.delete(gps_tracking)
end
def change_gps_tracking(%GPSTracking{} = gps_tracking) do
GPSTracking.changeset(gps_tracking, %{})
end
27. Controllers
defmodule TrackingAPIWeb.GPSTrackingController do
use TrackingAPIWeb, :controller
alias TrackingAPI.Tracking
alias TrackingAPI.Tracking.GPSTracking
action_fallback TrackingAPIWeb.FallbackController
def index(conn, _params) do
gps_tracking = Tracking.list_gps_tracking()
render(conn, "index.json", gps_tracking: gps_tracking)
end
def create(conn, %{"gps_tracking" => gps_tracking_params}) do
with {:ok, %GPSTracking{} = gps_tracking} <- Tracking.create_gps_tracking(gps_tracking_params) do
conn
|> put_status(:created)
|> put_resp_header("location", gps_tracking_path(conn, :show, gps_tracking))
|> render("show.json", gps_tracking: gps_tracking)
end
end
end
29. Views
def render("index.json", %{gps_tracking: gps_tracking}) do
%{data: render_many(gps_tracking, GPSTrackingView, "gps_tracking.json")}
end
def render("show.json", %{gps_tracking: gps_tracking}) do
%{data: render_one(gps_tracking, GPSTrackingView, "gps_tracking.json")}
end
def render("gps_tracking.json", %{gps_tracking: gps_tracking}) do
%{id: gps_tracking.id,
application_id: gps_tracking.application_id,
user_id: gps_tracking.user_id,
latitude: gps_tracking.latitude,
longitude: gps_tracking.longitude,
created_at: gps_tracking.created_at}
end
30. Router
defmodule TrackingAPIWeb.Router do
use TrackingAPIWeb, :router
pipeline :api do
plug :accepts, ["json"]
end
scope "/api", TrackingAPIWeb do
pipe_through :api
resources "/gps_tracking", GPSTrackingController, except: [:edit]
end
end
31. Testing
test "list_gps_tracking/0 returns all gps_tracking" do
gps_tracking = gps_tracking_fixture()
assert Tracking.list_gps_tracking() == [gps_tracking]
end
test "get_gps_tracking!/1 returns the gps_tracking with given id" do
gps_tracking = gps_tracking_fixture()
assert Tracking.get_gps_tracking!(gps_tracking.id) == gps_tracking
end
test "create_gps_tracking/1 with valid data creates a gps_tracking" do
assert {:ok, %GPSTracking{} = gps_tracking} = Tracking.create_gps_tracking(@valid_attrs)
assert gps_tracking.application_id == "7488a646-e31f-11e4-aace-600308960662"
assert gps_tracking.created_at == DateTime.from_naive!(~N[2010-04-17 14:00:00.000000Z], "Etc/UTC")
assert gps_tracking.latitude == "some latitude"
assert gps_tracking.longitude == "some longitude"
assert gps_tracking.user_id == "7488a646-e31f-11e4-aace-600308960662"
end
test "create_gps_tracking/1 with invalid data returns error changeset" do
assert {:error, %Ecto.Changeset{}} = Tracking.create_gps_tracking(@invalid_attrs)
end