Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ecto - the past, the present, the future

Ecto - the past, the present, the future

ElixirConfEU 2016 in Berlin

Michał Muskała

May 12, 2016
Tweet

More Decks by Michał Muskała

Other Decks in Programming

Transcript

  1. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    ECTO
    the past, the present, the future

    View Slide

  2. @michalmuskala ElixirConfEU, Berlin, 12.05.2016

    View Slide

  3. @michalmuskala ElixirConfEU, Berlin, 12.05.2016

    View Slide

  4. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    ECTO
    the past, the present, the future

    View Slide

  5. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Michał Muskała
    http://michal.muskala.eu/
    https://github.com/michalmuskala/
    @michalmuskala

    View Slide

  6. @michalmuskala ElixirConfEU, Berlin, 12.05.2016

    View Slide

  7. @michalmuskala ElixirConfEU, Berlin, 12.05.2016

    View Slide

  8. @michalmuskala ElixirConfEU, Berlin, 12.05.2016

    View Slide

  9. @michalmuskala ElixirConfEU, Berlin, 12.05.2016

    View Slide

  10. @michalmuskala ElixirConfEU, Berlin, 12.05.2016

    View Slide

  11. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Question time

    View Slide

  12. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Who’s using Ecto?

    View Slide

  13. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Who’s using mongodb_ecto?

    View Slide

  14. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Who’s using Ecto 2.0-
    whatever?

    View Slide

  15. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Ecto history

    View Slide

  16. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    v0.1.0 - 01.05.2014
    defmodule User do
    use Ecto.Model
    queryable "users" do
    field :name, :string
    field :age, :string
    end
    validate user,
    name: present(),
    age: present(message: "must be present"),
    age: greater_than(18)
    end

    View Slide

  17. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    fragments

    View Slide

  18. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    fragments
    v0.3.0

    View Slide

  19. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    :map type

    View Slide

  20. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    :map type
    v0.13.0

    View Slide

  21. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    associations

    View Slide

  22. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    associations
    v0.2.0

    View Slide

  23. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    changesets

    View Slide

  24. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    changesets
    v0.5.0

    View Slide

  25. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    timestamps

    View Slide

  26. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    timestamps
    v0.6.0

    View Slide

  27. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Ecto.Type

    View Slide

  28. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Ecto.Type
    v0.5.0

    View Slide

  29. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    embeds

    View Slide

  30. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    embeds
    v0.14.0

    View Slide

  31. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    MySQL

    View Slide

  32. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    MySQL
    v0.9.0

    View Slide

  33. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    inspirations

    View Slide

  34. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    SQL + NoSQL = ?

    View Slide

  35. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    v1.0.0
    25.08.2015

    View Slide

  36. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    v1.1.0
    25.08.2015

    View Slide

  37. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    v2.0.0
    ?

    View Slide

  38. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    v2.0.0-rc2145
    12.04.2025

    View Slide

  39. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    db_connection

    View Slide

  40. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    subqueries

    View Slide

  41. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    subqueries
    query = from p in Post,
    select: [:visits],
    order_by: [desc: :visits],
    limit: 10
    TestRepo.all(from p in subquery(query),
    select: avg(p.visits))

    View Slide

  42. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    many_to_many

    View Slide

  43. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    concurrent, transactional tests

    View Slide

  44. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    concurrent, transactional tests
    Ecto.Adapters.SQL.begin_test_transaction(MyApp.Repo)
    by
    Ecto.Adapters.SQL.Sandbox.mode(MyApp.Repo, :manual)
    and
    unless tags[:async] do
    Ecto.Adapters.SQL.restart_test_transaction(MyApp.Repo, [])
    end
    by
    :ok = Ecto.Adapters.SQL.Sandbox.checkout(MyApp.Repo)
    unless tags[:async] do
    Ecto.Adapters.SQL.Sandbox.mode(MyApp.Repo, {:shared, self()})
    end

    View Slide

  45. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    parallel preloads
    by default

    View Slide

  46. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    easier associations

    View Slide

  47. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    no callbacks

    View Slide

  48. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Ecto.Schema

    View Slide

  49. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    changeset changes

    View Slide

  50. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Ecto.Multi

    View Slide

  51. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Ecto.Multi
    defmodule UserManager do
    alias Ecto.Multi
    import Ecto
    def password_reset(params) do
    with {:ok, account} <- load_account(params),
    multi = password_reset_multi(account, params),
    {:ok, results} <- Repo.transaction(multi),
    :ok <- send_notification(results.account),
    do: {:ok, results}
    end
    # ...
    end

    View Slide

  52. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Ecto.Multi
    @doc false
    def password_reset_multi(account, params) do
    account = account_password_reset(account, params)
    access_log = log_password_reset(account, params)
    Multi.new
    |> Multi.update(:account, account)
    |> Multi.insert(:log, access_log)
    |> Multi.delete_all(:sessions, assoc(account, :sessions))
    end

    View Slide

  53. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    schemaless queries

    View Slide

  54. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    schemaless queries
    from u in "users",
    join: a in "activities",
    on: a.user_id == u.id,
    where: a.start_at > type(^start_at, Ecto.DateTime) and
    a.end_at < type(^end_at, Ecto.DateTime),
    group_by: a.user_id,
    select: %{user_id: a.user_id,
    interval: a.start_at - a.end_at,
    count: count(u.id)}

    View Slide

  55. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    schemaless queries
    # insert data
    [%{id: id}] =
    MyApp.Repo.insert_all("posts", [[title: "hello"]],
    returning: [:id])
    # use query for updates
    post = from p in "posts", where: p.id == ^id
    {1, _} = MyApp.Repo.update_all(post,
    set: [title: "new title"])
    # and deletes
    {1, _} = MyApp.Repo.delete_all post

    View Slide

  56. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    multiple schemas, same table

    View Slide

  57. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    tableless schemas

    View Slide

  58. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    tableless schemas
    defmoudule RegistrationSchema do
    use Ecto.Schema
    schema "" do
    field :foo, :string
    field :bar, :integer
    embeds_one :resource, Resource do
    field :baz, MyEctoType
    end
    end
    # ...
    end

    View Slide

  59. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    tableless schemas
    def validate(params) do
    %RegistrationSchema{}
    |> cast(params, [:foo, :bar, :baz])
    |> validate_required([:foo, :bar])
    |> # some other validations
    |> to_tuple
    end
    defp to_tuple(%{valid?: true} = c) do
    {:ok, apply_changes(c)}
    end
    defp to_tuple(%{errors: errors}) do
    {:error, errors}
    end

    View Slide

  60. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    schemaless changesets

    View Slide

  61. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    schemaless changesets
    data = %{}
    types = %{first_name: :string,
    last_name: :string,
    email: :string}
    fields = Map.keys(types)
    changeset =
    {data, types}
    |> Ecto.Changeset.cast(params, types)
    |> validate_required(...)
    |> validate_length(...)

    View Slide

  62. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    KISS

    View Slide

  63. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Future?

    View Slide

  64. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    tableless schemas
    defmoudule RegistrationSchema do
    use Ecto.Schema
    schema "" do
    field :foo, :string
    field :bar, :integer
    embeds_one :resource, Resource do
    field :baz, MyEctoType
    end
    end
    # ...
    end

    View Slide

  65. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Separate data and database

    View Slide

  66. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Ecto 2.0 is data-centric

    View Slide

  67. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Ecto 2.0 is less opinionated

    View Slide

  68. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Ecto 2.0 is not your model

    View Slide

  69. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Ecto 2.0 is not a solution

    View Slide

  70. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    Ecto 2.0 is a toolbox

    View Slide

  71. @michalmuskala ElixirConfEU, Berlin, 12.05.2016
    ECTO
    the past, the present, the future

    View Slide