繁体   English   中英

Elixir Phoenix:我可以从模板调用上下文函数吗,我应该吗?

[英]Elixir Phoenix: Can I call a context function from a template, and should I

我想在文章表单(用于创建和更新)中显示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"] %>

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

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

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

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

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

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

例如:一个新要求是get_categories现在只列出用户有权访问的类别。 使用控制器分配,您可以创建一个控制器测试,其中包含诸如assert conn.assigns.categories == ["one", "two"] 但是当您在视图中获取类别时,测试将变得类似于assert html_response(conn, 200) =~ "<li>one</li><li>two</li>" ,这要脆弱得多(即.它不能保证没有项目“三”,或者如果您向每个li元素添加一个类,那么您也必须更新测试)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM