Ecto:
An Introduction
Dan McClain
- Partner @ DockYard
- @_danmcclain
- GitHub: danmcclain
3 components
- Ecto.Repo
- Ecto.Model
- Ecto.Query
Ecto.Repo
- Database Wrapper
- Performs actions (insert, delete, get, update)
- Bullet One
- Bullet Two
- Bullet Three
# config.exs
config :ecto_examples, EctoExamples.Repo,
database: "ecto_examples",
username: "dan",
password: "",
hostname: "localhost"
# repo.ex
defmodule EctoExamples.Repo do
use Ecto.Repo,
otp_app: :ecto_examples,
adapter: Ecto.Adapters.Postgres
end
EctoExamples.Repo.insert user
EctoExamples.Repo.delete user
EctoExamples.Repo.all query
Migrations
- Bullet One
- Bullet Two
- Bullet Three
$ mix ecto.gen.migration initial_users_create # Generate a migration
# priv/repo/migrations/20150224173410_initial_users_create.exs
defmodule EctoExamples.Repo.Migrations.InitialUsersCreate do
use Ecto.Migration
def up do
create table(:users) do
add :token, :string
add :username, :string, null: false
timestamps
end
end
def down do
drop table(:users)
end
end
$ mix ecto.create # Create our database
$ mix ecto.migrate # Run migrations
$ mix ecto.rollback # Rollback migration
Ecto.Model
- Defines data structures
- Define changesets
- Allow you to validate changes
- Bullet One
- Bullet Two
- Bullet Three
defmodule EctoExamples.User do
alias EctoExamples.Repo
use Ecto.Model
schema "users" do
field :username
field :token
timestamps
end
# Contextual Validations <3
def changeset(:insert, user, params) do
params
# Required Optional
|> cast(user, ~w(username), ~w(token))
|> validate_unique(:username, on: Repo)
|> validate_format(:token, ~r/^\S*$/)
end
def changeset(:update, user, params) do
params
# Required Optional
|> cast(user, ~w(username token), ~w())
|> validate_unique(:username, on: Repo)
|> validate_format(:token, ~r/^\S*$/)
end
end
Ecto.Query
- Encapsulates query with DSL
- Inspired by .Net's LINQ
- Composable
- Bullet One
- Bullet Two
- Bullet Three
defmodule EctoExamples.UserQueries do
import Ecto.Query
def users_with_tokens do
from u in EctoExamples.User,
where: not(is_nil(u.token))
end
end
defmodule EctoExamples.Pagination do
import Ecto.Query
def page(query, page_number, page_size) do
_offset = (page_number - 1) * page_size
query
|> limit([q], ^page_size)
|> offset([q], ^_offset)
end
end
EctoExamples.Repo.all EctoExamples.UserQueries.users_with_tokens
EctoExamples.UserQueries.users_with_tokens
|> EctoExamples.Pagination.page(1,1)
|> EctoExamples.Repo.all
Questions?
Resources
- Jose Valim's talk from 2013: https://www.youtube.com/watch?v=SJRfujy9vLA
- Docs: http://hexdocs.pm/ecto/
- GitHub: https://github.com/elixir-lang/ecto
- Examples from this talk: https://github.com/danmcclain/ecto_examples
Ecto: An Introduction
By Dan McClain
Ecto: An Introduction
- 3,738