通过模板访问外部关系字段

时间:2017-09-10 11:55:43

标签: elixir phoenix-framework

假设我在凤凰应用程序中有这个模型。

defmodule Rumbl.Video do
  use Rumbl.Web, :model

  schema "videos" do
    field :url, :string
    field :title, :string
    field :description, :string
    belongs_to :user, Rumbl.User
    belongs_to :category, Rumbl.Category

    timestamps()
  end

  @required_fields ~w(url title description)
  @optional_fields ~w(category_id)

  def changeset(model, params \\ :empty) do
    model
    |> cast(params, @required_fields, @optional_fields)
  end

end

类别字段表示与Category模型的关系,该模型具有名为name的字段。

然后在模板中我有这个:

<%= for video <- @videos do %>
    <tr>
      <td><%= video.user_id %></td>
      <td><%= video.url %></td>
      <td><%= video.title %></td>
      <td><%= video.description %></td>
      <td><%= video.category_id %></td>

      <td class="text-right">
        <%= link "Show", to: video_path(@conn, :show, video), class: "btn btn-default btn-xs" %>
        <%= link "Edit", to: video_path(@conn, :edit, video), class: "btn btn-default btn-xs" %>
        <%= link "Delete", to: video_path(@conn, :delete, video), method: :delete, data: [confirm: "Are you sure?"], class: "btn btn-danger btn-xs" %>
      </td>
    </tr>
<% end %>

如您所见,我可以访问video.category_id

如何访问video.category.name以使其更具人性化?

编辑:视频控制器索引和类别部分

defmodule Rumbl.VideoController do
  use Rumbl.Web, :controller

  alias Rumbl.Video

  def action(conn, _) do
    apply(__MODULE__, action_name(conn),
          [conn, conn.params, conn.assigns.current_user])
  end

  def index(conn, _params, user) do
    videos = Repo.all(user_videos(user)) |> Repo.preload(:category)
    render(conn, "index.html", videos: videos)
  end

  alias Rumbl.Category

  plug :load_categories when action in  [:new, :create, :edit, :update]

  defp load_categories(conn, _) do
    query =
      Category
      |> Category.alphabetical
      |> Category.names_and_ids
    categories = Repo.all query
    assign(conn, :categories, categories)
  end
end

1 个答案:

答案 0 :(得分:5)

我假设您正在控制器中加载这样的视频:

videos = Repo.all(Video)

这不会加载相关记录。为此,您可以使用Repo.preload

videos = Repo.all(Video) |> Repo.preload(:category)

现在,每个视频的category字段都会加载所有字段,您可以在模板中执行<%= video.category.name %>