【问题标题】:Show related data from two schemas in the same eex template在同一个 eex 模板中显示来自两个模式的相关数据
【发布时间】:2016-09-26 22:57:47
【问题描述】:

我正在尝试在表单中显示一些相关数据。我有一个学生架构

schema "students" do
  field :firstname, :string
  field :lastname, :string
  field :birthday, Ecto.Date
  field :joined_on, Ecto.Date
  field :gender, :string
  timestamps()
end

每个学生都可以有一个母亲和一个父亲,我将他们指定为父母,并创建了一个单独的模式和单独的表。每个父记录最多可以与 1 个学生关联(奇怪,但适用于我的用例)。

schema "parents" do
  field :relationship, :string
  field :fullname, :string
  field :qualification, :string
  belongs_to :student, Myapp.Student, foreign_key :student_id
  timestamps()
end

我正在尝试创建一个可以同时创建新学生和家长的表单。因此,将以相同的形式存在学生字段和母亲和父亲字段。我尝试了多种方法在 eex 模板中获取此父母数据,但我失败了。

这是我在Student 控制器的new 方法中使用的:

def new (conn, _params) do
  changeset = Student.changeset(%Student{})
  render(conn, "new.html", [changeset: changeset])
end

我认为这里有问题,因为当我使用 Html 帮助程序时,我无法获取 eex 表单中的 parents 字段。我希望能够同时创造新的学生和家长。如果我可以使用相同的 eex 模板编辑它们,那就太好了。谢谢。

【问题讨论】:

  • 你缺少的第一个明显的东西是students 架构中的has_many :parents, Myapp.Parent。这能解决你的问题吗?如果没有,您可以发布您尝试过的 eex 表单代码吗?
  • 谢谢。是的,从下面的答案中错过了这一点以及更多内容

标签: elixir phoenix-framework ecto


【解决方案1】:

您需要在Student 模型中使用has_manycast_assoc

defmodule Myapp.Student do
  use Myapp.Web, :model

  schema "students" do
    field :firstname, :string
    field :lastname, :string
    field :birthday, Ecto.Date
    field :joined_on, Ecto.Date
    field :gender, :string
    has_many :parents, Myapp.Parent

    timestamps()
  end

  @doc """
  Builds a changeset based on the `struct` and `params`.
  """
  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:firstname, :lastname, :birthday, :joined_on, :gender])
    |> cast_assoc(:parents)
    |> validate_required([:firstname, :lastname, :birthday, :joined_on, :gender])
  end
end

web/templates/student/form.html.eex 中使用inputs_for

<%= inputs_for f, :parents, fn pf -> %>
  <h3>Parent form</h3>

  <div class="form-group">
    <%= label pf, :relationship, class: "control-label" %>
    <%= text_input pf, :relationship, class: "form-control" %>
    <%= error_tag pf, :relationship %>
  </div>

  <div class="form-group">
    <%= label pf, :fullname, class: "control-label" %>
    <%= text_input pf, :fullname, class: "form-control" %>
    <%= error_tag pf, :fullname %>
  </div>

  <div class="form-group">
    <%= label pf, :qualification, class: "control-label" %>
    <%= text_input pf, :qualification, class: "form-control" %>
    <%= error_tag pf, :qualification %>
  </div>
<% end %>

您可以在学生控制器操作new 中构建两个父母:

alias Myapp.Parent

def new(conn, _params) do
  changeset = Student.changeset(%Student{parents: [%Parent{}, %Parent{}]})
  render(conn, "new.html", changeset: changeset)
end

还需要在StudentController 中为editupdate 操作预加载:parents

student = Repo.get!(Student, id) |> Repo.preload(:parents)

代码 - https://github.com/shhavel/stackoverflow-questions-39683691

【讨论】:

  • 感谢您抽出宝贵时间详细回答这个问题!我开始了解 Ecto 的工作原理
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-21
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多