Packages
ecto
0.11.0
3.14.1
3.14.0
3.13.6
3.13.5
3.13.4
3.13.3
3.13.2
3.13.1
3.13.0
3.12.6
3.12.5
3.12.4
3.12.3
3.12.2
3.12.1
3.12.0
3.11.2
3.11.1
3.11.0
3.10.3
3.10.2
3.10.1
3.10.0
3.9.6
3.9.5
3.9.4
3.9.3
3.9.2
3.9.1
3.9.0
3.8.4
3.8.3
3.8.2
3.8.1
3.8.0
3.7.2
3.7.1
3.7.0
3.6.2
3.6.1
3.6.0
3.5.8
3.5.7
3.5.6
3.5.5
3.5.4
3.5.3
3.5.2
3.5.1
3.5.0
3.5.0-rc.1
3.5.0-rc.0
3.4.6
3.4.5
3.4.4
3.4.3
3.4.2
3.4.1
3.4.0
3.3.4
3.3.3
3.3.2
3.3.1
3.3.0
3.2.5
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
3.1.7
3.1.6
3.1.5
3.1.4
3.1.3
3.1.2
3.1.1
3.1.0
3.0.9
3.0.8
3.0.7
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
3.0.0-rc.1
3.0.0-rc.0
2.2.12
2.2.11
2.2.10
2.2.9
2.2.8
2.2.7
2.2.6
2.2.5
2.2.4
2.2.3
2.2.2
2.2.1
2.2.0
2.2.0-rc.1
2.2.0-rc.0
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.1.0-rc.5
2.1.0-rc.4
2.1.0-rc.3
2.1.0-rc.2
2.1.0-rc.1
2.1.0-rc.0
2.0.6
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
2.0.0-rc.6
2.0.0-rc.5
2.0.0-rc.4
2.0.0-rc.3
2.0.0-rc.2
2.0.0-rc.1
2.0.0-rc.0
2.0.0-beta.2
2.0.0-beta.1
2.0.0-beta.0
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.16.0
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
0.13.0
0.12.1
0.12.0
0.12.0-rc
0.11.3
0.11.2
0.11.1
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.0
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.0
0.5.1
0.5.0
0.4.0
0.3.0
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
A toolkit for data mapping and language integrated query for Elixir
Current section
Files
Jump to
Current section
Files
integration_test/cases/repo.exs
defmodule Ecto.Integration.RepoTest do
use Ecto.Integration.Case
require Ecto.Integration.TestRepo, as: TestRepo
import Ecto.Query
alias Ecto.Integration.Post
alias Ecto.Integration.PostUsecTimestamps
alias Ecto.Integration.Comment
alias Ecto.Integration.Permalink
alias Ecto.Integration.User
alias Ecto.Integration.Custom
alias Ecto.Integration.Barebone
alias Ecto.Schema.Metadata
test "returns already started for started repos" do
assert {:error, {:already_started, _}} = TestRepo.start_link
end
test "fetch empty" do
assert [] == TestRepo.all(Post)
assert [] == TestRepo.all(from p in Post)
end
test "fetch with in" do
TestRepo.insert(%Post{title: "hello"})
assert [] = TestRepo.all from p in Post, where: p.title in []
assert [] = TestRepo.all from p in Post, where: p.title in ["1", "2", "3"]
assert [] = TestRepo.all from p in Post, where: p.title in ^[]
assert [_] = TestRepo.all from p in Post, where: not p.title in []
assert [_] = TestRepo.all from p in Post, where: p.title in ["1", "hello", "3"]
assert [_] = TestRepo.all from p in Post, where: p.title in ["1", ^"hello", "3"]
assert [_] = TestRepo.all from p in Post, where: p.title in ^["1", "hello", "3"]
end
test "fetch without model" do
%Post{id: id} = TestRepo.insert(%Post{title: "title1"})
%Post{} = TestRepo.insert(%Post{title: "title2"})
assert ["title1", "title2"] =
TestRepo.all(from(p in "posts", order_by: p.title, select: p.title))
assert [^id] =
TestRepo.all(from(p in "posts", where: p.title == "title1", select: p.id))
end
test "insert, update and delete" do
post = %Post{title: "create and delete single", text: "fetch empty"}
deleted_meta = %Metadata{state: :deleted, source: "posts"}
assert %Post{} = to_be_deleted = TestRepo.insert(post)
assert %Post{__meta__: ^deleted_meta} = TestRepo.delete(to_be_deleted)
loaded_meta = %Metadata{state: :loaded, source: "posts"}
assert %Post{__meta__: ^loaded_meta} = TestRepo.insert(post)
post = TestRepo.one(Post)
assert post.__meta__.state == :loaded
assert post.inserted_at
post = %{post | text: "coming very soon..."}
post = put_in post.__meta__.state, :built
assert %Post{__meta__: ^loaded_meta} = TestRepo.update(post)
end
test "insert and update with changeset" do
# On insert we merge the fields and changes
changeset = Ecto.Changeset.cast(%Post{text: "x", title: "wrong"},
%{"title" => "hello", "temp" => "unknown"}, ~w(title temp), ~w())
post = TestRepo.insert(changeset)
assert %Post{text: "x", title: "hello", temp: "unknown"} = post
assert %Post{text: "x", title: "hello", temp: "temp"} = TestRepo.get!(Post, post.id)
# On update we merge only fields
changeset = Ecto.Changeset.cast(%{post | text: "y"},
%{"title" => "world", "temp" => "unknown"}, ~w(title temp), ~w())
assert %Post{text: "y", title: "world", temp: "unknown"} = TestRepo.update(changeset)
assert %Post{text: "x", title: "world", temp: "temp"} = TestRepo.get!(Post, post.id)
end
test "insert and update with empty changeset" do
# On insert we merge the fields and changes
changeset = Ecto.Changeset.cast(%Comment{}, %{}, ~w(), ~w())
assert %Comment{} = comment = TestRepo.insert(changeset)
# Assert we can update the same value twice,
# without changes, without triggering stale errors.
changeset = Ecto.Changeset.cast(comment, %{}, ~w(), ~w())
assert ^comment = TestRepo.update(changeset)
assert ^comment = TestRepo.update(changeset)
end
test "insert with no primary key" do
assert %Barebone{num: nil} = TestRepo.insert(%Barebone{})
assert %Barebone{num: 13} = TestRepo.insert(%Barebone{num: 13})
end
@tag :assigns_primary_key
test "insert with user-assigned primary key" do
assert %Post{id: 1} = TestRepo.insert(%Post{id: 1})
end
@tag :assigns_primary_key
test "insert and update with user-assigned primary key in changeset" do
changeset = Ecto.Changeset.cast(%Post{id: 11}, %{"id" => "13"}, ~w(id), ~w())
assert %Post{id: 13} = post = TestRepo.insert(changeset)
changeset = Ecto.Changeset.cast(post, %{"id" => "15"}, ~w(id), ~w())
assert %Post{id: 15} = TestRepo.update(changeset)
end
@tag :read_after_writes
test "insert and update with changeset dirty tracking" do
changeset = Ecto.Changeset.cast(%Post{}, %{}, ~w(), ~w())
# There is no dirty tracking on insert, even with changesets,
# so database defaults never actually kick in.
assert %Post{id: pid, counter: nil} = post = TestRepo.insert(changeset)
# Set the counter to 11, so we can read it soon
TestRepo.update(%{post | counter: 11})
# Now, a combination of dirty tracking with read_after_writes,
# allow us to see the actual counter value.
changeset = Ecto.Changeset.cast(post, %{"title" => "hello"}, ~w(title), ~w())
assert %Post{id: ^pid, counter: 11, title: "hello"} = post = TestRepo.update(changeset)
# Let's change the counter once more, so we can read it soon
TestRepo.update(%{post | counter: 13})
# And the value will be refreshed even if there are no changes
changeset = Ecto.Changeset.cast(post, %{}, ~w(), ~w())
assert %Post{id: ^pid, counter: 13, title: "hello"} = TestRepo.update(changeset)
end
test "validate_unique/3" do
import Ecto.Changeset
post = TestRepo.insert(%Post{title: "HELLO"})
on_insert = cast(%Post{}, %{"title" => "HELLO"}, ~w(title), ~w())
assert validate_unique(on_insert, :title, on: TestRepo).errors != []
on_insert = cast(%Post{}, %{"title" => "hello"}, ~w(title), ~w())
assert validate_unique(on_insert, :title, on: TestRepo, downcase: true).errors != []
on_update = cast(post, %{"title" => "HELLO"}, ~w(title), ~w())
assert validate_unique(on_update, :title, on: TestRepo).errors == []
on_update = cast(%{post | id: post.id + 1, title: nil}, %{"title" => "HELLO"}, ~w(title), ~w())
assert validate_unique(on_update, :title, on: TestRepo).errors != []
end
@tag :case_sensitive
test "validate_unique/3 case sensitive" do
import Ecto.Changeset
post = TestRepo.insert(%Post{title: "HELLO"})
on_insert = cast(%Post{}, %{"title" => "hello"}, ~w(title), ~w())
assert validate_unique(on_insert, :title, on: TestRepo).errors == []
on_update = cast(%{post | id: post.id + 1}, %{"title" => "hello"}, ~w(title), ~w())
assert validate_unique(on_update, :title, on: TestRepo).errors == []
end
test "validate_unique/3 with scope" do
import Ecto.Changeset
post = TestRepo.insert(%Post{title: "hello", text: "world"})
on_insert = cast(%Post{}, %{"title" => "hello", "text" => "elixir"}, ~w(title), ~w(text))
assert validate_unique(on_insert, :title, on: TestRepo).errors == [title: "has already been taken"]
assert validate_unique(on_insert, :title, scope: [:text], on: TestRepo).errors == []
assert_raise(Ecto.QueryError, fn ->
validate_unique(on_insert, :title, scope: [:non_existent], on: TestRepo).errors == []
end)
end
test "get(!)" do
post1 = TestRepo.insert(%Post{title: "1", text: "hai"})
post2 = TestRepo.insert(%Post{title: "2", text: "hai"})
assert post1 == TestRepo.get(Post, post1.id)
assert post2 == TestRepo.get(Post, to_string post2.id) # With casting
assert nil == TestRepo.get(Post, -1)
assert post1 == TestRepo.get!(Post, post1.id)
assert post2 == TestRepo.get!(Post, to_string post2.id) # With casting
assert_raise Ecto.NoResultsError, fn ->
TestRepo.get!(Post, -1)
end
end
test "get(!) with custom primary key" do
TestRepo.insert(%Custom{uuid: "01abcdef01abcdef"})
TestRepo.insert(%Custom{uuid: "02abcdef02abcdef"})
assert %Custom{uuid: "01abcdef01abcdef", __meta__: %{state: :loaded}} =
TestRepo.get(Custom, "01abcdef01abcdef")
assert %Custom{uuid: "02abcdef02abcdef", __meta__: %{state: :loaded}} =
TestRepo.get(Custom, "02abcdef02abcdef")
assert nil = TestRepo.get(Custom, "03abcdef03abcdef")
end
test "get(!) with custom source" do
custom = %Custom{uuid: "01abcdef01abcdef"}
custom = put_in custom.__meta__.source, "posts"
TestRepo.insert(custom)
assert %Custom{uuid: "01abcdef01abcdef", __meta__: %{source: "posts"}} =
TestRepo.get(from(c in {"posts", Custom}), "01abcdef01abcdef")
end
test "get_by(!)" do
post1 = TestRepo.insert(%Post{title: "1", text: "hai"})
post2 = TestRepo.insert(%Post{title: "2", text: "hello"})
assert post1 == TestRepo.get_by(Post, id: post1.id)
assert post1 == TestRepo.get_by(Post, text: post1.text)
assert post1 == TestRepo.get_by(Post, id: post1.id, text: post1.text)
assert post2 == TestRepo.get_by(Post, id: to_string(post2.id)) # With casting
assert nil == TestRepo.get_by(Post, text: "hey")
assert nil == TestRepo.get_by(Post, id: post2.id, text: "hey")
assert post1 == TestRepo.get_by!(Post, id: post1.id)
assert post1 == TestRepo.get_by!(Post, text: post1.text)
assert post1 == TestRepo.get_by!(Post, id: post1.id, text: post1.text)
assert post2 == TestRepo.get_by!(Post, id: to_string(post2.id)) # With casting
assert_raise Ecto.NoResultsError, fn ->
TestRepo.get_by!(Post, id: post2.id, text: "hey")
end
end
test "one(!)" do
post1 = TestRepo.insert(%Post{title: "1", text: "hai"})
post2 = TestRepo.insert(%Post{title: "2", text: "hai"})
assert post1 == TestRepo.one(from p in Post, where: p.id == ^post1.id)
assert post2 == TestRepo.one(from p in Post, where: p.id == ^to_string post2.id) # With casting
assert nil == TestRepo.one(from p in Post, where: p.id == ^-1)
assert post1 == TestRepo.one!(from p in Post, where: p.id == ^post1.id)
assert post2 == TestRepo.one!(from p in Post, where: p.id == ^to_string post2.id) # With casting
assert_raise Ecto.NoResultsError, fn ->
TestRepo.one!(from p in Post, where: p.id == ^-1)
end
end
test "one(!) with multiple results" do
assert %Post{} = TestRepo.insert(%Post{title: "hai"})
assert %Post{} = TestRepo.insert(%Post{title: "hai"})
assert_raise Ecto.MultipleResultsError, fn ->
TestRepo.one(from p in Post, where: p.title == "hai")
end
assert_raise Ecto.MultipleResultsError, fn ->
TestRepo.one!(from p in Post, where: p.title == "hai")
end
end
test "update all" do
assert %Post{id: id1} = TestRepo.insert(%Post{title: "1"})
assert %Post{id: id2} = TestRepo.insert(%Post{title: "2"})
assert %Post{id: id3} = TestRepo.insert(%Post{title: "3"})
assert 3 = TestRepo.update_all(Post, title: "x")
assert %Post{title: "x"} = TestRepo.get(Post, id1)
assert %Post{title: "x"} = TestRepo.get(Post, id2)
assert %Post{title: "x"} = TestRepo.get(Post, id3)
assert 3 = TestRepo.update_all("posts", title: "y")
assert %Post{title: "y"} = TestRepo.get(Post, id1)
assert %Post{title: "y"} = TestRepo.get(Post, id2)
assert %Post{title: "y"} = TestRepo.get(Post, id3)
end
test "update all with joins" do
user = TestRepo.insert(%User{name: "Tester"})
post = TestRepo.insert(%Post{title: "foo"})
comment = TestRepo.insert(%Comment{text: "hey", author_id: user.id, post_id: post.id})
query = from(c in Comment, join: u in User, on: u.id == c.author_id, where: c.post_id in ^[post.id])
assert 1 = TestRepo.update_all(query, text: "hoo")
assert %Comment{text: "hoo"} = TestRepo.get(Comment, comment.id)
end
test "update all with filter" do
assert %Post{id: id1} = TestRepo.insert(%Post{title: "1"})
assert %Post{id: id2} = TestRepo.insert(%Post{title: "2"})
assert %Post{id: id3} = TestRepo.insert(%Post{title: "3"})
query = from(p in Post, where: p.title == "1" or p.title == "2")
assert 2 = TestRepo.update_all(query, title: "x", text: ^"y")
assert %Post{title: "x", text: "y"} = TestRepo.get(Post, id1)
assert %Post{title: "x", text: "y"} = TestRepo.get(Post, id2)
assert %Post{title: "3", text: nil} = TestRepo.get(Post, id3)
end
test "update all no entries" do
assert %Post{id: id1} = TestRepo.insert(%Post{title: "1"})
assert %Post{id: id2} = TestRepo.insert(%Post{title: "2"})
assert %Post{id: id3} = TestRepo.insert(%Post{title: "3"})
query = from(p in Post, where: p.title == "4")
assert 0 = TestRepo.update_all(query, title: "x")
assert %Post{title: "1"} = TestRepo.get(Post, id1)
assert %Post{title: "2"} = TestRepo.get(Post, id2)
assert %Post{title: "3"} = TestRepo.get(Post, id3)
end
test "update all expression syntax" do
assert %Post{id: id1} = TestRepo.insert(%Post{title: "1", visits: 0})
assert %Post{id: id2} = TestRepo.insert(%Post{title: "2", visits: 1})
# Expressions
query = from p in Post, where: p.id > 0
assert 2 = TestRepo.update_all(p in query, visits: fragment("? + 2", p.visits))
assert %Post{visits: 2} = TestRepo.get(Post, id1)
assert %Post{visits: 3} = TestRepo.get(Post, id2)
# Nil values
assert 2 = TestRepo.update_all(p in Post, visits: nil)
assert %Post{visits: nil} = TestRepo.get(Post, id1)
assert %Post{visits: nil} = TestRepo.get(Post, id2)
end
test "update all with casting and dumping" do
text = "hai"
date = Ecto.DateTime.utc
assert %Post{id: id1} = TestRepo.insert(%Post{})
assert 1 = TestRepo.update_all(p in Post, text: ^text, counter: ^to_string(id1), inserted_at: ^date)
assert %Post{text: "hai", counter: ^id1, inserted_at: ^date} = TestRepo.get(Post, id1)
text = "hai"
date = {{2010, 4, 17}, {14, 00, 00, 00}}
assert %Comment{id: id2} = TestRepo.insert(%Comment{})
assert 1 = TestRepo.update_all(p in Comment, text: ^text, posted: ^date)
assert %Comment{text: "hai", posted: ^date} = TestRepo.get(Comment, id2)
date = {{1955, 11, 12}, {6, 38, 01, 0}}
assert 1 = TestRepo.update_all(p in Comment, text: ^text, posted: ^date)
assert %Comment{text: "hai", posted: ^date} = TestRepo.get(Comment, id2)
end
test "delete all" do
assert %Post{} = TestRepo.insert(%Post{title: "1", text: "hai"})
assert %Post{} = TestRepo.insert(%Post{title: "2", text: "hai"})
assert %Post{} = TestRepo.insert(%Post{title: "3", text: "hai"})
assert 3 = TestRepo.delete_all(Post)
assert [] = TestRepo.all(Post)
end
test "delete all with filter" do
assert %Post{} = TestRepo.insert(%Post{title: "1", text: "hai"})
assert %Post{} = TestRepo.insert(%Post{title: "2", text: "hai"})
assert %Post{} = TestRepo.insert(%Post{title: "3", text: "hai"})
query = from(p in Post, where: p.title == "1" or p.title == "2")
assert 2 = TestRepo.delete_all(query)
assert [%Post{}] = TestRepo.all(Post)
end
test "delete all with joins" do
user = TestRepo.insert(%User{name: "Tester"})
post = TestRepo.insert(%Post{title: "foo"})
TestRepo.insert(%Comment{text: "hey", author_id: user.id, post_id: post.id})
TestRepo.insert(%Comment{text: "foo", author_id: user.id, post_id: post.id})
TestRepo.insert(%Comment{text: "bar", author_id: user.id})
query = from(c in Comment, join: u in User, on: u.id == c.author_id, where: c.post_id in ^[post.id])
assert 2 = TestRepo.delete_all(query)
assert [%Comment{}] = TestRepo.all(Comment)
end
test "delete all no entries" do
assert %Post{id: id1} = TestRepo.insert(%Post{title: "1", text: "hai"})
assert %Post{id: id2} = TestRepo.insert(%Post{title: "2", text: "hai"})
assert %Post{id: id3} = TestRepo.insert(%Post{title: "3", text: "hai"})
query = from(p in Post, where: p.title == "4")
assert 0 = TestRepo.delete_all(query)
assert %Post{title: "1"} = TestRepo.get(Post, id1)
assert %Post{title: "2"} = TestRepo.get(Post, id2)
assert %Post{title: "3"} = TestRepo.get(Post, id3)
end
test "virtual field" do
assert %Post{id: id} = TestRepo.insert(%Post{title: "1", text: "hai"})
assert TestRepo.get(Post, id).temp == "temp"
end
## Joins
test "joins" do
p1 = TestRepo.insert(%Post{title: "1"})
p2 = TestRepo.insert(%Post{title: "2"})
c1 = TestRepo.insert(%Permalink{url: "1", post_id: p2.id})
query = from(p in Post, join: c in assoc(p, :permalink), order_by: p.id, select: {p, c})
assert [{^p2, ^c1}] = TestRepo.all(query)
query = from(p in Post, left_join: c in assoc(p, :permalink), order_by: p.id, select: {p, c})
assert [{^p1, nil}, {^p2, ^c1}] = TestRepo.all(query)
end
test "has_many association join" do
post = TestRepo.insert(%Post{title: "1", text: "hi"})
c1 = TestRepo.insert(%Comment{text: "hey", post_id: post.id})
c2 = TestRepo.insert(%Comment{text: "heya", post_id: post.id})
query = from(p in Post, join: c in assoc(p, :comments), select: {p, c}, order_by: p.id)
[{^post, ^c1}, {^post, ^c2}] = TestRepo.all(query)
end
test "has_one association join" do
post = TestRepo.insert(%Post{title: "1", text: "hi"})
p1 = TestRepo.insert(%Permalink{url: "hey", post_id: post.id})
p2 = TestRepo.insert(%Permalink{url: "heya", post_id: post.id})
query = from(p in Post, join: c in assoc(p, :permalink), select: {p, c}, order_by: c.id)
[{^post, ^p1}, {^post, ^p2}] = TestRepo.all(query)
end
test "belongs_to association join" do
post = TestRepo.insert(%Post{title: "1"})
p1 = TestRepo.insert(%Permalink{url: "hey", post_id: post.id})
p2 = TestRepo.insert(%Permalink{url: "heya", post_id: post.id})
query = from(p in Permalink, join: c in assoc(p, :post), select: {p, c}, order_by: p.id)
[{^p1, ^post}, {^p2, ^post}] = TestRepo.all(query)
end
## Assocs
test "has_many assoc" do
p1 = TestRepo.insert(%Post{title: "1"})
p2 = TestRepo.insert(%Post{title: "1"})
%Comment{id: cid1} = TestRepo.insert(%Comment{text: "1", post_id: p1.id})
%Comment{id: cid2} = TestRepo.insert(%Comment{text: "2", post_id: p1.id})
%Comment{id: cid3} = TestRepo.insert(%Comment{text: "3", post_id: p2.id})
[c1, c2] = TestRepo.all Ecto.Model.assoc(p1, :comments)
assert c1.id == cid1
assert c2.id == cid2
[c1, c2, c3] = TestRepo.all Ecto.Model.assoc([p1, p2], :comments)
assert c1.id == cid1
assert c2.id == cid2
assert c3.id == cid3
end
test "has_one assoc" do
p1 = TestRepo.insert(%Post{title: "1"})
p2 = TestRepo.insert(%Post{title: "2"})
%Permalink{id: lid1} = TestRepo.insert(%Permalink{url: "1", post_id: p1.id})
%Permalink{} = TestRepo.insert(%Permalink{url: "2"})
%Permalink{id: lid3} = TestRepo.insert(%Permalink{url: "3", post_id: p2.id})
[l1, l3] = TestRepo.all Ecto.Model.assoc([p1, p2], :permalink)
assert l1.id == lid1
assert l3.id == lid3
end
test "belongs_to assoc" do
%Post{id: pid1} = TestRepo.insert(%Post{title: "1"})
%Post{id: pid2} = TestRepo.insert(%Post{title: "2"})
l1 = TestRepo.insert(%Permalink{url: "1", post_id: pid1})
l2 = TestRepo.insert(%Permalink{url: "2"})
l3 = TestRepo.insert(%Permalink{url: "3", post_id: pid2})
assert [p1, p2] = TestRepo.all Ecto.Model.assoc([l1, l2, l3], :post)
assert p1.id == pid1
assert p2.id == pid2
end
test "has_many through assoc" do
%Post{id: pid1} = p1 = TestRepo.insert(%Post{})
%Post{id: pid2} = p2 = TestRepo.insert(%Post{})
%User{id: uid1} = TestRepo.insert(%User{name: "zzz"})
%User{id: uid2} = TestRepo.insert(%User{name: "aaa"})
%Comment{} = TestRepo.insert(%Comment{post_id: pid1, author_id: uid1})
%Comment{} = TestRepo.insert(%Comment{post_id: pid1, author_id: uid1})
%Comment{} = TestRepo.insert(%Comment{post_id: pid1, author_id: uid2})
%Comment{} = TestRepo.insert(%Comment{post_id: pid2, author_id: uid2})
[u2, u1] = TestRepo.all Ecto.Model.assoc([p1, p2], :comments_authors)
|> order_by([a], a.name)
assert u1.id == uid1
assert u2.id == uid2
end
test "optimistic locking in update/delete operations" do
import Ecto.Changeset, only: [cast: 4]
base_post = TestRepo.insert(%Permalink{})
cs_ok = cast(base_post, %{"url" => "http://foo.bar"}, ~w(url), ~w())
TestRepo.update(cs_ok)
cs_stale = cast(base_post, %{"url" => "http://foo.baz"}, ~w(url), ~w())
assert_raise Ecto.StaleModelError, fn -> TestRepo.update(cs_stale) end
assert_raise Ecto.StaleModelError, fn -> TestRepo.delete(cs_stale) end
end
@tag :uses_usec
test "insert and fetch a model with timestamps with usec" do
p1 = TestRepo.insert(%PostUsecTimestamps{title: "hello"})
assert [p1] == TestRepo.all(PostUsecTimestamps)
end
end