Elixir's Ecto library makes it incredibly easy to handle more advanced SQL queries. In this presentation, I go over how to store public data in a more performant fashion.
8. defmodule GMB.Reviews.Review do
use Ecto.Schema
schema "reviews" do
field :id, :string
field :author, :string
field :rating, :integer
field :reply, :string
field :created_at, :utc_datetime
field :updated_at, :utc_datetime
field :deleted_at, :utc_datetime
end
end
(ArgumentError) field/association :id
is already set on schema
9. defmodule GMB.Reviews.Review do
use Ecto.Schema
@primary_key {:id, :string, []}
schema "reviews" do
field :author, :string
field :comment, :string
field :rating, :integer
field :reply, :string
field :created_at, :utc_datetime
field :updated_at, :utc_datetime
field :deleted_at, :utc_datetime
end
end
10. defmodule GMB.Repo.Migrations.CreateReviews do
use Ecto.Migration
def change do
create table(:reviews) do
add :author, :string, null: false, default: ""
add :rating, :integer, null: false, default: 0
add :comment, :string, null: false, default: ""
add :reply, :string, null: false, default: ""
add :created_at, :naive_datetime, null: false, default: "epoch"
add :updated_at, :naive_datetime, null: false, default: "epoch"
add :deleted_at, :naive_datetime, null: false, default: "epoch"
end
end
end
11. defmodule GMB.Reviews.Review do
use Ecto.Schema
@primary_key {:id, :string, []}
schema "reviews" do
field :author, :string
field :comment, :string
field :rating, :integer
field :reply, :string
field :created_at, :utc_datetime
field :updated_at, :utc_datetime
field :deleted_at, :utc_datetime
end
end
14. User
id - Integer
first_name - String
last_name - String
email - String
Group
id - Integer
name - String
description - String
slug - String
Member
user_id - Integer
group_id - Integer
role - String
15. defmodule SirAlex.Groups.Member do
use Ecto.Schema
alias SirAlex.Groups.{Group, User}
@primary_key false
schema "members" do
field :role, :string, default: "member"
belongs_to :group, Group
belongs_to :user, User
timestamps()
end
end
16. defmodule SirAlex.Repo.Migrations.CreateMembers do
use Ecto.Migration
def change do
create table(:members, primary_key: false) do
add :group_id, references(:groups), primary_key: true
add :user_id, references(:users), primary_key: true
add :role, :string, null: false, default: "member"
timestamps()
end
end
end
22. defmodule GMB.Reviews do
alias GMB.Repo
alias GMB.Reviews.Review
def save_reviews(reviews) do
Enum.map(reviews, &save_review/1)
end
def save_review(attrs) do
%Review{}
|> Review.changeset(attrs)
|> Repo.insert()
end
end
27. defmodule GMB.Reviews do
alias GMB.Repo
alias GMB.Reviews.Review
def save_reviews(reviews) do
Enum.map(reviews, &save_review/1)
end
def save_review(attrs) do
%Review{}
|> Review.changeset(attrs)
|> Repo.insert()
end
end
28. defmodule GMB.Reviews do
alias GMB.Repo
alias GMB.Reviews.Review
def save_reviews(reviews) do
Repo.insert_all(Review, reviews)
end
end
No validation?! 😱
35. def save_reviews(reviews) do
opts = [on_conflict: :replace_all]
Repo.insert_all(Review, reviews, opts)
end
** (Postgrex.Error) ERROR 42601
(syntax_error): ON CONFLICT DO UPDATE
requires inference specification or
constraint name
51. Further Reading
• Plataformatec - What’s New in Ecto 2.1
http://pages.plataformatec.com.br/ebook-whats-new-in-ecto-2-0
• Ecto Docs!
https://hexdocs.pm/ecto/Ecto.html
• @dnsbty on twitter