属于多个父母

时间:2016-04-20 16:56:53

标签: elixir phoenix-framework ecto

您好我是Elixir和模型/数据库/ API的新手一般而且我在如何实现以下方面有点迷失:

我想在我的API中发帖时创建一个活动/v1/events发送tag_idgate_id,但我不知道如何处理这个问题。控制器。

我已经使用更简单的模型完成了这项工作,他们只有belong_to一位父母,而我只是在build_assoc中管道changeset,但是,我迷失了如何与多个父母一起做。我甚至尝试了一个粗略的解决方案,手动创建一个变更集,手动设置gate_idtag_id,就像这样Event.changeset(%Event{"gate_id" => gate_id, "tag_id" => tag_id}, event_params),但它错误地说gate_idtag_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

1 个答案:

答案 0 :(得分:2)

您是否可以针对Event发布错误和迁移?我相信您需要将tag_idgate_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