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

Avatar for Michał Muskała

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 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
  2. @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))
  3. @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
  4. @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
  5. @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
  6. @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)}
  7. @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
  8. @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
  9. @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
  10. @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(...)
  11. @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