- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我预期会发生什么:当尝试插入一个已经存在用户名的角色时,调用 Repo.insert 返回给我详细信息错误的变更集。
发生了什么 Ecto 引发了一个硬性异常
我的 Phoenix 项目出现以下错误。
** (exit) an exception was raised:
** (Ecto.ConstraintError) constraint error when attempting to insert struct:
* personas_username_index (unique_constraint)
If you would like to stop this constraint violation from raising an
exception and instead add it as an error to your changeset, please
call `unique_constraint/3` on your changeset with the constraint
`:name` as an option.
The changeset has not defined any constraint.
所以我听从了它的建议,在我的数据库中添加了唯一索引的名称,personas_username_index
。这个唯一索引肯定存在于真正的底层数据库中。
这是我的架构:
defmodule Poaster.Persona do
use Ecto.Schema
import Ecto.Changeset
alias Poaster.User
schema "personas" do
belongs_to :user, User
field :background_image_url, :string
field :bio, :string
field :name, :string
field :profile_image_url, :string
field :username, :string
timestamps()
end
@doc false
def changeset(persona, attrs) do
persona
|> cast(attrs, [:username, :name, :bio, :profile_image_url, :background_image_url, :user])
|> validate_required([:username])
|> unique_constraint(:username, name: :personas_username_index)
end
end
这是我的 Controller 代码:
def create(conn, %{"username" => username}) do
# First attempt
# result = Ecto.build_assoc(conn.assigns[:signed_user], :personas, %{ username: username })
# IO.inspect(result)
# result = Repo.insert(result)
# IO.inspect(result)
user = conn.assigns[:signed_user]
result = Repo.insert(%Persona{username: username, user: user})
case result do
{:ok, persona} ->
conn
|> put_status(:created)
|> json(persona_data(persona))
{:error, _changeset} ->
conn
|> put_status(:internal_server_error)
|> json(%{
success: false,
error: %{
detail: "There was an error saving your username!"
}
})
end
end
defp persona_data(persona) do
%{
id: persona.id,
background_image_url: persona.background_image_url,
bio: persona.bio,
inserted_at: persona.inserted_at,
name: persona.name,
profile_image_url: persona.profile_image_url,
updated_at: persona.updated_at,
username: persona.username
}
end
迁移文件:
defmodule Poaster.Repo.Migrations.CreatePersonas do
use Ecto.Migration
def change do
create table(:personas) do
add :username, :string, null: false
add :name, :string
add :bio, :string
add :profile_image_url, :string
add :background_image_url, :string
add :user_id, references(:users, on_delete: :nothing), null: false
timestamps()
end
create unique_index(:personas, [:username])
create index(:personas, [:user_id])
end
end
最佳答案
我认为您应该插入一个变更集,而不是直接插入模式,以便能够捕获错误,如文档中所述:
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3-complex-constraints
您正在 Persona.changeset/2
函数中调用 unique_constraint/3
,但您没有在中调用 Persona.changeset/2
你的 Controller 代码。
我认为您应该替换以下行:
result = Repo.insert(%Persona{username: username, user: user}
通过:
result = %Persona{}
|> Persona.changeset(%{username: username, user: user})
|> Repo.insert()
或者更确切地说,在执行此操作的上下文中定义一个 create_persona/1
函数,并从您的 Controller 调用该函数(至少这是生成器的组织方式)它)。
关于elixir - Phoenix/Elixir/Ecto - unique_constraint 不适用于名称选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63403245/
docs状态 run(t, name, module, function, args) :: t when function: atom, args: [any] Similar to run/3,
目前,我正在寻找在运行 mix 任务时添加 SQL 语句日志记录的方法。例如,mix ecto.rollback 和 mix ecto.migrate 等命令输出信息: ... 13:45:53.01
我有两张 table 。 topics的表其中has_many tweets .我的表tweets belongs_to topic . 主题架构: defmodule Sentiment.Topic
今天,和往常一样,我尝试制作 混合 ecto.migrate 在我的 Phoenix 应用程序中,意外地发现了以下错误: warning: could not find repositories fo
我可以使用什么函数来检查关联是否已经加载? 最好检查关联是否已加载,而不是尝试使用它并获取 Ecto.Association.NotLoaded错误。 最佳答案 您可以使用 assoc_loaded?
我在 postgresql 中有一个表,我想用一个随机数更新所有记录的“points”列的值。在其他语言中,我们可以循环遍历所有数据库记录,但我如何使用 ecto 来做到这一点?我试过这个: Rep
在处理具有关联的模型时,加载关联模型的最佳实践是什么:显式使用 Repo.preload 或指定在定义查询时应预加载的关联? 最佳答案 它们是等效的,因此任何方法都可以,真的。如果您想将所有内容都放在
有什么办法可以逆向预加载吗? %Post{ comments: [] } posts = Repo.all(Post) |> Repo.unload(:comments) %Post{ com
使用 Ecto 访问大写字段的最佳方式是什么? 我必须处理一个相当困惑的模式。有些列是大写的。 我设置了以下模型: defmodule SourcesApi.SourceStatus do use
在下面的链接中做了一些研究之后 https://github.com/elixir-lang/ecto/tree/master/examples/simple 我对如何在 elixir 中使用 ect
有没有办法通过选择另一个连接列来预加载记录? # table structure # User 1---* Post 1---* PostTag *---1 Tag # extract definit
考虑以下架构: defmodule EctoBug.Post do use Ecto.Schema import Ecto.Changeset schema "posts" do
这些都不起作用: from m in Model, where: m.name == ^~r(/.*#{query}.*/i)from m in Model, where: m.name =~ ^~r
假设我有这些模式: defmodule Sample.Post do use Ecto.Schema schema "post" do field :title has_man
我有一个针对多个数据库的应用程序,它就像一个监视应用程序的应用程序,它以一种不可能静态控制的方式(在配置文件中)生成报告、调解通知、运行任务和东西,所以我认为它可以启动一个监督多个 Repo 的主管来
我正在尝试编写单个变更集,以更新模型并插入关联。我找不到有关如何使用 put_assoc/4 的示例 order = order |> Proj.Order.changeset(%{sta
我正在寻找所有 User在其 match_history 中没有特定字符串元素的 s field 。我对此进行了猜测: matched_user = User |> where([u], ^devic
我无法成功运行 Ecto 迁移以删除最初创建时提供的唯一索引 :name属性(以便不使用默认索引名称)。但是,我现在无法删除该索引,因为似乎 Ecto 正在尝试查找名称不正确的索引(尽管我已经提供了它
为什么在 Ecto changeset方法您是否将参数设置为默认值:empty原子?例如 def changeset(user, params \\ :empty) do ... 这是否允许您使
注意:我使用的是 MySQL 5.7。 我有两个名为 Post、Comment 的表 schema "posts" do field: id, string field :titl
我是一名优秀的程序员,十分优秀!