string = "hello"
atom = :some_atom
tuple = {"nice", "tuple"}
map = %{some: "other", :structure => 1}
list = [123, 321, 34, "hello"]
keywords = [desc: :e_fame], # [{:desc, :e_fame}]
[head | tail] = [1, 2, 3]
assert head == 1
assert tail == [2, 3]
%{title: some_title} = %{title: "super", description: "blah blah blah"}
assert some_title == "super"
defmodule HumanTalks.Host do
def thank_you(message) do
case message do
%{type: :mail, title: title, sender: sender} ->
# send automatic mail
%{type: :sms, content: content, sender: sender} ->
# automatic Text
other_message ->
IO.puts "hey we received an unknown message: #{inspect(other_type)}"
end
end
end
Disclaimer: this is not a tutorial
defmodule HumanTalks.Host do
use Ecto.Schema
schema "hosts" do
field :name # Defaults to type :string
field :email
field :encrypted_password_super_secure # md5 hash
field :e_fame, :integer, default: -5
field :last_response, Ecto.DateTime
end
end
defmodule HumanTalks.WhosWho do
import Ecto.Query, only: [from: 2]
alias HumanTalks.Host
alias HumanTalks.Repo
def most_famous_host do
query = from(h in Host,
where: not is_nil(h.e_fame),
order_by: [desc: :e_fame],
select: {h.name, h.email},
limit: 1)
Repo.one(query)
end
end
defmodule HumanTalks.WelcomeHost do
import Ecto.Changeset
alias HumanTalks.Host
def new_host(params \\ %{}) do
%Host{}
|> cast(params, [:name, :email, :e_fame])
|> validate_required([:name, :email])
|> validate_format(:email, ~r/@/)
|> validate_number(:e_fame, :greater_than_or_equal_to, 0)
|> unique_constraint(:email)
end
end
defmodule HumanTalks.Reception do
alias HumanTalks.WelcomeHost
def welcome_new_host(params) do
insert_changes = WelcomeHost.new_host(params)
# insert_changes.is_valid? == true
case Repo.insert(insert_changes) do
{:ok, host} ->
# host.name == params["name"]
{:error, changeset} ->
IO.inspect changeset.errors
#=> [email: {"has already been taken", []}]
end
end
end
defmodule Post do
use Ecto.Schema
schema "posts" do
field :name, :string
field :age, :integer, default: 0
has_many :comments, Comment
end
end
# Create a query
query = from p in Post,
join: c in Comment, where: c.post_id == p.id
# Extend the query
query = from [p, c] in query,
select: {p.title, c.body}
# Or
query = from p in Post, preload: [:comments]
Multi
defmodule HumanTalks.PasswordManager do
alias Ecto.Multi
def reset(account, params) do
Multi.new
|> Multi.update(:account, Account.password_reset_changeset(account, params))
|> Multi.insert(:log, Log.password_reset_changeset(account, params))
|> Multi.delete_all(:sessions, Ecto.assoc(account, :sessions))
end
def perform(multi) do
HumanTalks.Repo.transaction(multi)
end
end
test "dry run password reset" do
account = %HumanTalks.Host{password: "letmein"}
multi = HumanTalks.PasswordManager.reset(account, params)
assert [
{:account, {:update, account_changeset, []}},
{:log, {:insert, log_changeset, []}},
{:sessions, {:delete_all, query, []}}
] = Ecto.Multi.to_list(multi)
# We can introspect changesets and query to see if everything
assert account_changeset.valid?
assert log_changeset.valid?
assert inspect(query) == "#Ecto.Query<from a in Session>"
end
defmofule Stack do
use GenServer
def handle_call(:pop, _from, [h | t]) do
{:reply, h, t}
end
def handle_cast({:push, item}, state) do
{:noreply, [item | state]}
end
end
{:ok, pid} = GenServer.start_link(Stack, [:hello])
GenServer.call(pid, :pop) #=> :hello
GenServer.cast(pid, {:push, :world}) #=> :ok
GenServer.call(pid, :pop) #=> :world