Skip to content

Instantly share code, notes, and snippets.

@ray-sh
Last active March 21, 2020 09:26
Show Gist options
  • Save ray-sh/8c6313c0de65857fce12252eb02c3ec1 to your computer and use it in GitHub Desktop.
Save ray-sh/8c6313c0de65857fce12252eb02c3ec1 to your computer and use it in GitHub Desktop.
Common code snips for coding Phoenix
#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