Some days ago Ecto version 2.0.0-rc.5 has been released. So Ecto 2 is coming and exploring how it works and its new features is a good idea.
First, from hex.pm, Ecto is a domain specific language to write queries and interacting with databases in Elixir.
This version has four main components: Ecto.Repo
, Ecto.Schema
, Ecto.Query
, Ecto.Changeset
. Note here the absence of Ecto.Model
that has been deprecated in favor of a more data-oriented approach.
Let’s try it by creating a sample Elixir application.
mix new --sup my_shop
This command uses mix
to create our application while the --sup
option generates an OTP application skeleton that includes a supervision tree.
Now we are going to edit mix.exs file in order to include some dependencies at their latest versions: ecto and postgrex.
def application do
[applications: [:logger, :ecto, :postgrex],
mod: {MyShop, []}]
end
defp deps do
[
{:ecto, "~> 2.0.0-rc.5"},
{:postgrex, "~> 0.11.1"}
]
end
Run mix deps.get
and we’re ready to define our repo.
defmodule MyShop do
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [
supervisor(MyShop.Repo, [])
]
opts = [strategy: :one_for_one, name: MyShop.Supervisor]
Supervisor.start_link(children, opts)
end
end
defmodule MyShop.Repo do
use Ecto.Repo, otp_app: :my_shop
end
Note that we are defining our repo supervised by our app.
Repositories are the way you use to communicate with datastore, they are wrappers around our databases and you can define as many as we need and configure them in config/config.exs
. This is my configuration:
use Mix.Config
config :my_shop,
ecto_repos: [MyShop.Repo]
config :my_shop, MyShop.Repo,
adapter: Ecto.Adapters.Postgres,
url: "postgres://my_shop_user:my_shop_password@localhost:5432/my_shop_dev"
Now we can run the specific mix task mix ecto.create
and your database should be created.
We need some tables so let’s define a migration. In priv/repo/migrations/20160516233500_create_tables.exs:
defmodule MyShop.Repo.Migrations.CreateTables do
use Ecto.Migration
def change do
create table(:products) do
add :name, :string
add :description, :text
add :cost, :integer
end
create table(:colors) do
add :code, :string
end
create table(:order_items) do
add :product_id, references(:products)
add :color_id, references(:colors)
add :quantity, :integer
add :cost, :integer
end
create table(:orders) do
add :order_item_id, references(:order_items)
end
create table(:addresses) do
add :country, :string
end
end
end
Run mix ecto.migrate
and we’re done, we have five tables.
Now we are ready to use Ecto.Schema:
defmodule Product do
use Ecto.Schema
schema "products" do
field :name, :string
field :description, :string
field :cost, :integer
end
end
Schemas are used to map any data source into an Elixir struct. Note that it’s not mandatory to use all the table fields, just those you need.
Now run iex -S mix
in order to load your application into iex and verify if it works:
iex(1)> %Product{}
%Product{__meta__: #Ecto.Schema.Metadata<:built>, cost: nil, description: nil,
id: nil, name: nil}
iex(2)> %Unexistent{}
** (CompileError) iex:2: Unexistent.__struct__/0 is undefined, cannot expand struct Unexistent
(elixir) src/elixir_map.erl:58: :elixir_map.translate_struct/4
Now, let’s use our repo to insert a record in our data store:
MyShop.Repo.insert(%Product{name: "Programming Elixir"})
13:43:52.298 [debug] QUERY OK db=26.0ms
INSERT INTO "products" ("name") VALUES ($1) RETURNING "id" ["Programming Elixir"]
{:ok,
%Product{__meta__: #Ecto.Schema.Metadata<:loaded>, cost: nil, description: nil,
id: 1, name: "Programming Elixir"}}
Import Ecto.Query and retrieve all the products in our table:
iex(4)> import Ecto.Query
nil
iex(5)> MyShop.Repo.all(from p in Product)
13:46:18.400 [debug] QUERY OK db=1.4ms
SELECT p0."id", p0."name", p0."description", p0."cost" FROM "products" AS p0 []
[%Product{__meta__: #Ecto.Schema.Metadata<:loaded>, cost: nil, description: nil,
id: 1, name: "Programming Elixir"}]
It works 🙂
In my next post I’ll try to go deeper with more complex queries and introduce changesets.
If you are interested in this subject, Plataformatec will release an ebook about Ecto 2.0 written by José Valim, Elixir creator, you can reserve a copy here.
Leave a Reply