【问题标题】:Ecto: How to validate presence of belongs_to association?Ecto:如何验证 belongs_to 关联的存在?
【发布时间】:2017-04-13 12:04:00
【问题描述】:
defmodule ParrotApi.Meetup do

    schema "meetups" do
      field :timestamp, :integer
      belongs_to :topic, ParrotApi.Topic

      timestamps()
    end


    @required_fields ~w(timestamp)

    def changeset(struct, params \\ %{}) do
      struct
      |> cast(params, @required_fields)
      |> cast_assoc(:topic, required: true)
      |> validate_required(@required_fields)
    end

end

但是当我在测试中这样做时:

%Meetup{timestamp: future_time, topic_id: topic.id} |> Repo.insert

它没有通过错误:

iex(10)> %Meetup{timestamp: 123123} |> Repo.insert
[debug] QUERY OK db=0.3ms
begin []
[debug] QUERY OK db=1.3ms
INSERT INTO "meetups" ("timestamp","inserted_at","updated_at") VALUES ($1,$2,$3) RETURNING "id" [123123, {{2017, 4, 13}, {12, 3, 24, 644065}}, {{2017, 4, 13}, {12, 3, 24, 644074}}]
[debug] QUERY OK db=1.6ms
commit []
{:ok,
 %ParrotApi.Meetup{__meta__: #Ecto.Schema.Metadata<:loaded, "meetups">, id: 6,
  inserted_at: ~N[2017-04-13 12:03:24.644065], timestamp: 123123,
  topic: #Ecto.Association.NotLoaded<association :topic is not loaded>,
  topic_id: nil, updated_at: ~N[2017-04-13 12:03:24.644074]}}
iex(11)>

如何确保仅在存在 topic_id 的情况下进行 Meetup?

【问题讨论】:

  • 如果您直接创建 Struct 并将其发送到数据库,则不会运行 Ecto 验证。为此,您需要将此约束添加到数据库字段。
  • 抱歉,我是 Ecto 的新手。还有另一种创建聚会的方法吗?我认为这是它的语法
  • 是的,Meetup.changeset(%Meetup{}, %{timestamp: 123123}) |&gt; Repo.insert
  • 嗯,它告诉我** (ArgumentError) could not convert the parameter 'timestamp,' into an atom, 'timestamp,' is not a schema field
  • nvm 已修复!它不喜欢我模型中的@required_fields。谢谢!!!

标签: elixir phoenix-framework ecto


【解决方案1】:

尝试在字段中使用原子而不是字符串。我认为 required_fields 想要原子。此外,如果您想添加 topic_id,您还需要列出该字段。只需更改为@required_fields ~w(timestamp topic_id)a。也可以尝试在您拨打cast 之后立即拨打required_fields

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-30
    • 2017-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多