Last active
March 21, 2020 09:26
-
-
Save ray-sh/8c6313c0de65857fce12252eb02c3ec1 to your computer and use it in GitHub Desktop.
Common code snips for coding Phoenix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#A plug to get cookies from conn | |
defmodule AuthorizedPlug do | |
import Plug.Conn | |
import Phoenix.Controller | |
def init(options) do | |
options | |
end | |
def call(conn, name) do | |
user_name = conn.cookies["user_name"] | |
authorize_user(conn, user_name, name) | |
end | |
end | |
# A method to set cookie | |
defmodule LoginController do | |
use RsvpWeb.Web, :controller | |
def login(conn, %{"login" => %{"username" => name}}) do | |
expiration = 60*60*24*7 | |
conn | |
|> Plug.Conn.put_resp_cookie("user_name", name, max_age: expiration) | |
|> redirect(to: "/") | |
end | |
end | |
# A schemal which validate the require/optional filed and other validation | |
defmodule Events do | |
use Ecto.Schema | |
import Ecto.Changeset | |
schema "events" do | |
field :title, :string | |
field :location, :string | |
field :date, Ecto.DateTime | |
field :description, :string | |
field :quantity_available, :integer, default: 25 | |
timestamps | |
end | |
@required_fields ~w(title location date)a | |
@optional_fields ~w(description)a | |
def changeset(event, params \\ %{}) do | |
event | |
|> cast(params, @required_fields ++ @optional_fields) | |
|> validate_required(@required_fields) | |
|> validate_change(:date, &must_be_future/2) | |
end | |
defp must_be_future(_, value) do | |
Ecto.DateTime.compare(value, Ecto.DateTime.utc) | |
|> get_error | |
end | |
defp get_error(comparison) when comparison == :lt, do: [date: "cannot be in the past"] | |
defp get_error(_), do: [] | |
end | |
#A login form, parameters will contains login key | |
<%= form_for @conn, login_path(@conn, :login), [as: :login], fn f -> %> | |
<%= text_input f, :username %> | |
<%= submit "Login" %> | |
<% end %> | |
# Query module to inteact with DB | |
defmodule EventQueries do | |
import Ecto.Query | |
alias Rsvp.{Repo, Events} | |
def any do | |
Repo.one(from e in Events, select: count(e.id)) != 0 | |
end | |
def get_all do | |
Repo.all(from Events) | |
end | |
def get_all_for_location(location) do | |
query = from e in Events, | |
where: e.location == ^location | |
Repo.all(query) | |
end | |
def get_by_id(id) do | |
Repo.get(Events, id) | |
end | |
def create(event) do | |
Repo.insert(event) | |
end | |
def decrease_quantity(id, quantity) do | |
event = Repo.get!(Events, id) | |
changes = Ecto.Changeset.change event, quantity_available: event.quantity_available - String.to_integer(quantity) | |
Repo.update changes | |
end | |
end | |
# Method to insert item to database, data -> changeset -> db | |
def add(conn, %{"events" => events}) do | |
events = Map.update!(events, "date", fn x -> x <> ":00" end) | |
changeset = Rsvp.Events.changeset(%Rsvp.Events{}, events) | |
case Rsvp.EventQueries.create changeset do | |
{:ok, %{id: id}} -> redirect conn, to: event_path(conn, :show, id) | |
{:error, reasons} -> create conn, %{errors: reasons} | |
end | |
end | |
#Plug usage, plug only support k/v list | |
plug :auth when action in [:index, :show] | |
plug :one | |
plug Two | |
plug :three, some: options | |
# imported into the current module first. | |
import AnotherModule, only: [interesting_plug: 2] | |
plug :interesting_plug | |
# Test plug | |
https://hexdocs.pm/plug/Plug.Test.html#content | |
use ExUnit.Case, async: true | |
use Plug.Test | |
#DB migrate and rollback, by having up/down in the migration file, we could do db up/back change | |
def up do | |
create table(:admin) do | |
add :name, :string | |
add :email, :string | |
add :password, :string | |
timestamps() | |
end | |
end | |
def down do | |
drop table(:admin) | |
end | |
$ mix ecto.migrate | |
You can also it rollback by calling | |
$ mix ecto.rollback |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment