【问题标题】:Display records on index page with Elixir and Phoenix使用 Elixir 和 Phoenix 在索引页面上显示记录
【发布时间】:2017-11-23 14:49:38
【问题描述】:

我正在尝试使用理解来显示数据库中的记录。但我不能完全Comprehend(坏笑话)出了什么问题?错误消息,虽然我确定它告诉我出了什么问题,但我不明白它想说什么。

错误:

UndefinedFunctionError at GET /leagues
function Statcasters.Schema.League.fetch/2 is undefined (Statcasters.Schema.League does not implement the Access behaviour)


%Statcasters.Schema.League{__meta__: #Ecto.Schema.Metadata<:loaded, "leagues">, id: 1, inserted_at: ~N[2017-11-22 03:36:47.999950], name: "nae", teams: #Ecto.Association.NotLoaded<association :teams is not loaded>, updated_at: ~N[2017-11-22 03:36:47.999956], user: #Ecto.Association.NotLoaded<association :user is not loaded>, user_id: 1}

查看:

<h1>Join a League</h1>

<%= for league <- @leagues do %>
  <%= league["name"] %>
<% end %>

型号:

联赛:

defmodule Statcasters.Schema.League do
  use Ecto.Schema
  import Ecto
  import Ecto.Changeset
  import Ecto.Query

  schema "leagues" do
    field :name, :string
    has_many :teams, Statcasters.Teams.Team
    belongs_to :user, Statcasters.Coherence.User

    timestamps()
  end

  def changeset(struct, params \\ %{}) do
    struct
      |> cast(params, [:name, :user_id])
      |> validate_required([:name, :user_id])
  end
end

用户:

defmodule Statcasters.Coherence.User do
  @moduledoc false
  use Ecto.Schema
  use Coherence.Schema

  schema "users" do
    field :name, :string
    field :email, :string
    coherence_schema()
    has_many :leagues, Statcasters.Schema.League

    timestamps()
  end

  def changeset(model, params \\ %{}) do
    model
    |> cast(params, [:name, :email] ++ coherence_fields())
    |> validate_required([:name, :email])
    |> validate_format(:email, ~r/@/)
    |> unique_constraint(:email)
    |> validate_coherence(params)
  end

  def changeset(model, params, :password) do
    model
    |> cast(params, ~w(password password_confirmation reset_password_token reset_password_sent_at))
    |> validate_coherence_password_reset(params)
  end
end

联赛控制器:

  def index(conn, _params) do
    leagues = Repo.all(League)

    render(conn, "index.html", leagues: leagues)
  end

同样,我要做的只是在联赛索引页面上按名称列出系统中的所有联赛。感谢您的帮助!

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    你应该替换这一行:

    <%= league["name"] %>
    

    用这个:

    <%= league.name %>
    

    league 是一个结构,为了能够读取它的属性,您需要使用点符号。

    【讨论】:

      【解决方案2】:

      有三种不同的方法可以解决这个问题。

      1. 最简单的方法是只使用点表示法,如 @PawełDawczak 所示,因为 Elixir 中的结构不实现开箱即用的 Access 行为:

      league.name
      

      2. 但是,裸映射确实实现了Access,并且在字段名称是动态的情况下,可以选择将结构转换为带有Map.from_struct/1 的裸映射以访问具有Access 行为的属性:

      Map.from_struct(league)[:name]
      

      3. 第三种方法是为您的结构实现访问行为:

      defmodule League do
        defstruct ~w|name|a
      
        @behaviour Access
      
        def fetch(term, :name), do: term.name
        def fetch(term, "name"), do: term.name
        def fetch(term, name), do: raise KeyError, "no #{name} key"
      
        def get(term, :name, default), do: fetch(term, :name)
        def get(term, "name", default), do: fetch(term, :name)
        def get(term, _, default), do: default
      
        def get_and_update(data, key, function), do ...
        def pop(data, key), do: ...
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-04-15
        • 1970-01-01
        • 2017-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多