Notes
Commands
Create new API project:
$ mix phx.new project-name --no-html --no-webpackCreate database:
with database online
$ mix ecto.createInstall dependencies:
$ mix deps.getCreate config file for credo:
$ mix credo.gen.configCreate a migration
$ mix ecto.gen.migration migration_nameRun migrations
$ mix ecto.migrateElixir
Manipulate maps
map = %{a: 1, b: 2}
IO.puts map[:a]
map2 = %{"a" => 1, "b" => 1}
IO.puts map["a"]we can use Map.get/2 to get the value
iex> map = %{"a" => 1, "b" => 1}
iex> Map.get(map, "a")
1we can use Map.get/3 to get the value of a index, or a default value
iex> map = %{"a" => 1, "b" => 1}
iex> map["name"]
nil
iex> Map.get(map, "name")
nil
iex> Map.get(map, "name", 5)
5Phoenix
Use UUID as primary key
On config/config.exs add the config:
config :project, Project.Repo,
migration_primary_key: [type: :binary_id],
migration_foreign_key: [type: :binary_id]Use resources to create default routes of a controller
On lib/project_web/router.ex:
scope "/api", ProjectWeb do
pipe_through :api
resources "/some-route", SomeController
endThis will create all default route for SomeController, running mix phx.routes we will get:
some_path GET /api/some-route ProjectWeb.SomeController :index
some_path GET /api/some-route/:id/edit ProjectWeb.SomeController :edit
some_path GET /api/some-route/new ProjectWeb.SomeController :new
some_path GET /api/some-route/:id ProjectWeb.SomeController :show
some_path POST /api/some-route ProjectWeb.SomeController :create
some_path PATCH /api/some-route/:id ProjectWeb.SomeController :update
PUT /api/some-route/:id ProjectWeb.SomeController :update
some_path DELETE /api/some-route/:id ProjectWeb.SomeController :delete
We can pass the parameter only to specify the methods:
scope "/api", ProjectWeb do
pipe_through :api
resources "/some-route", SomeController, only: [:create, :show]
endBamboo
First add bamboo to deps on mix.ex:
defp deps do
[
{:bamboo, "~> 2.1.0"}
]
endUse Local Adapter
On config/config.exs add:
config :inmana, Inmana.Mailer, adapter: Bamboo.LocalAdapterto use in teste, add the config on config/test.exs:
config :inmana, Inmana.Mailer, adapter: Bamboo.TestAdapterUse dev router to see sent emails
On lib/project_web/router.ex:
if Mix.env() == :dev do
forward "/sent_emails", Bamboo.SentEmailViewerPlug
endGenServer
save code
defmodule Inmana.Supplies.Scheduler do
use GenServer
def init(state \\ %{}) do
{:ok, state}
end
# async
def handle_cast({:put, key, value}, state) do
{:noreply, Map.put(state, key, value)}
end
# sync
def handle_call({:get, key}, _from, state) do
{:reply, Map.get(state, key), state}
end
endTests
Common tests
use ExUnit.Case
describe "function/1" do
test "description for this test" do
params = "The params for the function"
expected_result = "Expected result"
result = Module.function(params)
assert result == expected_result
end
endChangeset tests
use Project.DataCase
alias Ecto.Changeset
describe "changeset/1" do
test "when all params are valid, return a valid changeset" do
params = %{name: "Siri cascudo", email: "siri@cascudo.com"}
response = Schema.changeset(params)
assert %Changeset{
changes: %{
name: "Siri cascudo",
email: "siri@cascudo.com"
},
valid?: true
} = response
end
test "when there are invalid params, returns a invalid changeset" do
params = %{name: "S", email: ""}
expected_response = %{
email: ["can't be blank"],
name: ["should be at least 2 character(s)"]
}
response = Schema.changeset(params)
assert %Changeset{valid?: false} = response
assert errors_on(response) == expected_response
end
endController tests
use ProjectWeb.ConnCase
describe "create/2" do
test "when all params are valid, create user", %{conn: conn} do
params = %{name: "Siri cascudo", email: "siri@cascudo.com"}
response =
conn
|> post(Routes.controller_path(conn, :create, params))
|> json_response(:created)
assert %{
"message" => "User Created!",
"user" => %{
"email" => "siri@cascudo.com",
"id" => _id,
"name" => "Siri cascudo"
}
} = response
end
test "when there are invalid params, return an error", %{conn: conn} do
params = %{email: "siri@cascudo.com"}
expected_response = %{"message" => %{"name" => ["can't be blank"]}}
response =
conn
|> post(Routes.controller_path(conn, :create, params))
|> json_response(:bad_request)
assert response == expected_response
end
endView tests
use ProjectWeb.ConnCase
import Phoenix.View
alias ProjectWeb.UserView
describe "render/2" do
test "renders create.json" do
params = %{name: "Siri cascudo", email: "siri@cascudo.com"}
{:ok, restaurant} = Project.create_user(params)
response = render(UserView, "create.json", user: user)
assert %{
message: "User Created!",
user: %User{
email: "siri@cascudo.com",
id: _id,
name: "Siri cascudo"
}
} = response
end
end
referencies
Rocketseat: https://rocketseat.com.br/