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
  2. @michalmuskala ElixirConfEU, Berlin, 12.05.2016

  3. @michalmuskala ElixirConfEU, Berlin, 12.05.2016

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

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

  6. @michalmuskala ElixirConfEU, Berlin, 12.05.2016

  7. @michalmuskala ElixirConfEU, Berlin, 12.05.2016

  8. @michalmuskala ElixirConfEU, Berlin, 12.05.2016

  9. @michalmuskala ElixirConfEU, Berlin, 12.05.2016

  10. @michalmuskala ElixirConfEU, Berlin, 12.05.2016

  11. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 Question time

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

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

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

  15. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 Ecto history

  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
  17. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 fragments

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

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

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

  21. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 associations

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

  23. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 changesets

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

  25. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 timestamps

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

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

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

  29. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 embeds

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

  31. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 MySQL

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

  33. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 inspirations

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

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

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

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

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

  39. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 db_connection

  40. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 subqueries

  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))
  42. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 many_to_many

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

  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
  45. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 parallel preloads by default

  46. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 easier associations

  47. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 no callbacks

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

  49. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 changeset changes

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

  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
  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
  53. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 schemaless queries

  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)}
  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
  56. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 multiple schemas, same table

  57. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 tableless schemas

  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
  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
  60. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 schemaless changesets

  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(...)
  62. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 KISS

  63. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 Future?

  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
  65. @michalmuskala ElixirConfEU, Berlin, 12.05.2016 Separate data and database

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

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

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

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

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

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

    future