我遵循了本教程,我的简单测试总是因为这个错误而失败
1) test /index returns a list of contacts (WorldNote.ChatsControllerTest)
test/controllers/chats_controller_test.exs:16
** (RuntimeError) cannot begin test transaction because we are already inside one
stacktrace:
(ecto) lib/ecto/adapters/sql.ex:321: anonymous fn/6 in Ecto.Adapters.SQL.start_test_transaction/3
(ecto) lib/ecto/adapters/sql.ex:615: Ecto.Adapters.SQL.pool_transaction/4
(ecto) lib/ecto/adapters/sql.ex:314: Ecto.Adapters.SQL.start_test_transaction/3
test/controllers/chats_controller_test.exs:9: WorldNote.ChatsControllerTest.__ex_unit_setup_0/1
test/controllers/chats_controller_test.exs:1: WorldNote.ChatsControllerTest.__ex_unit__/2
Run Code Online (Sandbox Code Playgroud)
代码很简单
defmodule WorldNote.ChatsControllerTest do
use ExUnit.Case, async: false
use Plug.Test
alias WorldNote.Chats
alias WorldNote.Repo
alias Ecto.Adapters.SQL
setup do
SQL.begin_test_transaction(Repo)
on_exit fn ->
SQL.rollback_test_transaction(Repo)
end
end
test "/index returns a list of contacts" do
contacts_as_json =
%Chats{fbid: 1234567890, latitude: …Run Code Online (Sandbox Code Playgroud) 我有这个架构:
schema "editables" do
field :title, :string
field :content, :binary
timestamps
end
Run Code Online (Sandbox Code Playgroud)
我希望在应用程序启动时自动创建和填充几行,说我想创建:title包含以下字段的6个条目:page1,page2,......我应该这样做吗?
在我的Tag模型代码中
schema "tags" do
field :name, :string
field :parent, :integer # parent tag id
timestamps
end
def add_error_when_not_exists_tag_id(changeset, params) do
tags = Repo.all(Tag)
is_exists_tag_id = Enum.reduce(tags, fn(x, acc) -> acc || (x.id === params.parent) end)
if is_exists_tag_id, do: changeset, else: add_error(changeset, :parent, "not exists parent!")
end
Run Code Online (Sandbox Code Playgroud)
上面的代码导致下面的错误.
(UndefinedFunctionError) undefined function: Repo.all/1 (module Repo is not available)
Run Code Online (Sandbox Code Playgroud)
我可以修复错误吗?
Tag模型是嵌套标签模型.
标签可以有父标签.
最终代码如下.这很好.
在模型中
def add_error_when_not_exists_tag_id(changeset, params, tags) do
is_exists_tag_id = Enum.reduce(tags, false, fn(x, acc) -> acc || (Integer.to_string(x.id) …Run Code Online (Sandbox Code Playgroud) 我正在尝试以编程方式将预加载附加到我的某个具有has_many, through:关系的模型的查询中.
我的模块:
defmodule MyApp.Chemical do
use MyApp.Web, :model
schema "chemicals" do
has_many :company_chemicals, MyApp.CompanyChemical
has_many :companies, through: [:company_chemicals, :companies]
field :name, :string
end
def with_companies(query) do
from chem in query,
left_join: comp_chem in assoc(chem, :company_chemicals),
join: company in assoc(comp_chem, :company),
preload: [companies: company]
end
end
defmodule MyApp.Company do
use MyApp.Web, :model
schema "companies" do
has_many :company_chemicals, MyApp.CompanyChemical
has_many :chemicals, through: [:company_chemicals, :chemicals]
field :name, :string
end
end
defmodule MyApp.CompanyChemical do
use MyApp.Web, :model
schema "company_chemicals" do
belongs_to …Run Code Online (Sandbox Code Playgroud) 我有团队,每个团队都有用户,因此有一个连接表将用户链接到团队,因为它有多对多关系,这是我的模型:
defmodule App.Team do
use App.Web, :model
schema "teams" do
field :owner_id, :integer
has_many :team_users, {"team_user", App.TeamUser}
end
end
defmodule App.User do
use App.Web, :model
schema "users" do
# field :email, :string
has_many :team_user, App.TeamUser
end
end
Run Code Online (Sandbox Code Playgroud)
这是连接模型:
defmodule App.TeamUser do
use App.Web, :model
@primary_key false
schema "team_user" do
belongs_to :user, App.User
belongs_to :team, App.Team
end
end
Run Code Online (Sandbox Code Playgroud)
如果我运行查询以获得所有结果团队用户的用户的所有团队,如下所示:
teams_users =
from(t in Team, where: t.owner_id == ^user_id)
|> Repo.all()
|> Repo.preload(:team_users)
Run Code Online (Sandbox Code Playgroud)
我得到这个日志:
[%App.Team{__meta__: #Ecto.Schema.Metadata<:loaded>, id: 1,
is_base_team: true, owner_id: 3, …Run Code Online (Sandbox Code Playgroud) 在我的应用程序中执行upsert很常见,我想实现最简洁的方法来实现upsert.
我可以使用什么功能来检查是否已加载关联?检查是否加载了关联而不是尝试使用它并获得Ecto.Association.NotLoaded错误会很好.
我在Elixir项目中整合协议实现时遇到问题.更具体地说,我使用了Ecto一些简单的项目Gold(无关紧要).问题是,它们(Ecto和Gold)都Poison用于序列化Decimals(并实现适当的协议).
Ecto外观的实现有点像这样:
defimpl Poison.Encoder, for: Decimal do
def encode(decimal, _opts), do: <<?", Decimal.to_string(decimal)::binary, ?">>
end
Run Code Online (Sandbox Code Playgroud)
在开发期间,有一个警告说该模块是重复的:
warning: redefining module Poison.Encoder.Decimal (current version loaded from /(...)/_build/dev/lib/gold/ebin/Elixir.Poison.Encoder.Decimal.beam)
lib/ecto/poison.ex:2
Run Code Online (Sandbox Code Playgroud)
但是当我尝试使用例如exrm构建版本时,我会收到错误,说我有duplicate_modules
===> Provider (release) failed with: {error,
{rlx_prv_assembler,
{release_script_generation_error,
systools_make,
{duplicate_modules,
[{{'Elixir.Poison.Encoder.Decimal',
gold,
"/(...)/rel/bitcoin_api/lib/gold-0.12.0/ebin"},
{'Elixir.Poison.Encoder.Decimal',
ecto,
"/(...)/rel/bitcoin_api/lib/ecto-2.0.2/ebin"}}]}}}}
Run Code Online (Sandbox Code Playgroud)
我应该怎么处理这个?这里的情况是我实际使用我自己的版本Gold,所以我可以篡改它来尽快解决它.我知道我可以再补充Ecto到Gold作为依赖,但似乎有点矫枉过正,只是实现一个协议是这样的.是否有某种宏来检查模块是否已经实现?
我正在开始我的Elixir/Phoenix之旅并且在我的postgres连接上遇到了一些麻烦.
当我启动我的服务器时,我得到:
$ mix phoenix.server
[error] Postgrex.Protocol (#PID<0.214.0>) failed to connect: ** (Postgrex.Error) tcp connect: connection refused - :econnrefused
[error] Postgrex.Protocol (#PID<0.217.0>) failed to connect: ** (Postgrex.Error) tcp connect: connection refused - :econnrefused
[error] Postgrex.Protocol (#PID<0.218.0>) failed to connect: ** (Postgrex.Error) tcp connect: connection refused - :econnrefused
[error] Postgrex.Protocol (#PID<0.211.0>) failed to connect: ** (Postgrex.Error) tcp connect: connection refused - :econnrefused
[error] Postgrex.Protocol (#PID<0.215.0>) failed to connect: ** (Postgrex.Error) tcp connect: connection refused - :econnrefused
[error] Postgrex.Protocol (#PID<0.219.0>) failed to …Run Code Online (Sandbox Code Playgroud) 我试图寻找User在他们的match_history领域中没有某个字符串元素的所有s .我猜了一下:
matched_user = User |> where([u], ^device_id not in u.match_history) |> limit(1) |> VideoChat.Repo.one
但它似乎打破了not部分.有没有办法做到这一点?