【问题标题】:Elixir Phoenix: Can I call a context function from a template, and should IElixir Phoenix:我可以从模板中调用上下文函数吗?我应该
【发布时间】:2021-11-08 22:36:38
【问题描述】:

我想以文章形式(用于创建和更新)显示article_categories 的列表作为下拉输入。

我的博客上下文 (blog.ex) 中有一个函数可以通过 Ecto 检索所有类别并将结果格式化为可下拉列表:

defmodule MyApp.Blog do
  import Ecto.Query, warn: false
  alias MyApp.Repo

  alias MyApp.Blog.ArticleCategory

  def get_categories() do
    MyApp.Repo.all from c in ArticleCategory, select: {c.title, c.id}
  end
end

在我的模板 (templates/article/form.html.heex) 中,我这样称呼我的类别:

<%= select f, :category_id, MyApp.Blog.get_categories(), prompt: [key: "Choose your category"] %>

视觉上我得到了我想要的结果,但是...文献似乎暗示将我的类别作为分配传递。

这样做有问题吗? (性能?设计?)

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    我完全赞成将这种逻辑放入控制器中。这里的主要动机是关注点分离

    • 您的控制器负责解析传入的参数并从数据/业务层获取正确的数据
    • 您的视图层负责将数据呈现给用户

    其中一个优点是您最终会得到一个更易于维护和测试的系统。

    我想很难理解为什么这是最佳实践,但随着您的应用程序的增长,它会显示出来。

    例如:一个新要求是get_categories 现在只列出用户有权访问的类别。使用控制器分配,您可以创建一个包含 assert conn.assigns.categories == ["one", "two"] 之类的控制器测试。但是,当您在视图中获取类别时,测试会变成类似于 assert html_response(conn, 200) =~ "&lt;li&gt;one&lt;/li&gt;&lt;li&gt;two&lt;/li&gt;" 的东西,它更加脆弱(即,它不能保证没有项目“三”,或者如果您为每个 @987654324 添加一个类@element 那么你也必须更新测试)。

    【讨论】:

    • 我明白你的意思:在上述情况下,上下文模块独立于conn。如果列表在控制器中处理,那么我可以将其与角色基础问题相匹配(按照您的示例)。谢谢。
    猜你喜欢
    • 2017-01-04
    • 2016-03-24
    • 1970-01-01
    • 2022-11-17
    • 2023-03-25
    • 2018-08-10
    • 2011-08-20
    • 2018-08-02
    • 1970-01-01
    相关资源
    最近更新 更多