您好我是Elixir和模型/数据库/ API的新手一般而且我在如何实现以下方面有点迷失:
我想在我的API中发帖时创建一个活动/v1/events
发送tag_id
和gate_id
,但我不知道如何处理这个问题。控制器。
我已经使用更简单的模型完成了这项工作,他们只有belong_to
一位父母,而我只是在build_assoc
中管道changeset
,但是,我迷失了如何与多个父母一起做。我甚至尝试了一个粗略的解决方案,手动创建一个变更集,手动设置gate_id
和tag_id
,就像这样Event.changeset(%Event{"gate_id" => gate_id, "tag_id" => tag_id}, event_params)
,但它错误地说gate_id
和tag_id
不是该模型的一部分。
所以有两个问题: 处理这种情况的正确方法是什么?我甚至关闭或我的模特错了吗?
对/v1/events
传递这两个ID的帖子听起来还是不错,或者我也丢失了?
参考模型
标记模型:
defmodule Tracker.Tag do
use Tracker.Web, :model
schema "tags" do
field :epc, :string
field :name, :string
field :is_active, :boolean, default: false
field :is_inside, :boolean, default: false
has_many :events, Tracker.Event
timestamps
end
@required_fields ~w(epc name is_active is_inside)
@optional_fields ~w()
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
|> cast_assoc(:events, required: false)
end
end
门模型:
defmodule Tracker.Gate do
use Tracker.Web, :model
schema "gates" do
field :name, :string
field :direction_in, :boolean, default: false
field :antenna, :integer
belongs_to :reader, Tracker.Reader
has_many :events, Tracker.Event
timestamps
end
@required_fields ~w(name direction_in antenna)
@optional_fields ~w()
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
|> cast_assoc(:events, required: false)
end
end
更新:更多信息
活动模型:
defmodule Tracker.Event do
use Tracker.Web, :model
schema "events" do
belongs_to :tag, Tracker.Tag
belongs_to :gate, Tracker.Gate
timestamps
end
@required_fields ~w()
@optional_fields ~w()
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
end
end
事件迁移:
defmodule Tracker.Repo.Migrations.CreateV1.Event do
use Ecto.Migration
def change do
create table(:events) do
add :tag_id, references(:tags, on_delete: :nothing)
add :gate_id, references(:gates, on_delete: :nothing)
timestamps
end
create index(:events, [:tag_id])
create index(:events, [:gate_id])
end
end
事件控制器创建功能(此类丢失的种类)
def create(conn, %{"event" => event_params}) do
gate_id = conn.assigns.gate_id
tag_id = conn.assigns.tag_id
changeset = Event.changeset(%Event{"gate_id" => gate_id, "tag_id" => tag_id}, event_params)
case Repo.insert(changeset) do
{:ok, event} ->
conn
|> put_status(:created)
|> put_resp_header("location", v1_event_path(conn, :show, event))
|> render("show.json", event: event)
{:error, changeset} ->
conn
|> put_status(:unprocessable_entity)
|> render(Tracker.ChangesetView, "error.json", changeset: changeset)
end
end
我得到的最新错误是
== Compilation error on file web/controllers/v1/event_controller.ex ==
** (CompileError) web/controllers/v1/event_controller.ex:22: unknown key "gate_id" for struct Tracker.Event
答案 0 :(得分:2)
您是否可以针对Event
发布错误和迁移?我相信您需要将tag_id
和gate_id
添加到模型中的必填字段:
defmodule Tracker.Event do
use Tracker.Web, :model
schema "events" do
belongs_to :tag, Tracker.Tag
belongs_to :gate, Tracker.Gate
timestamps
end
@required_fields ~w(tag_id gate_id)
@optional_fields ~w()
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
end
end