我是Elixir / Phoenix的新手,我想创建一个不使用模型ID但最终出现错误的链接:
protocol Enumerable not implemented for %XX.YY.Article{__meta__: #Ecto.Schema.Metadata<:built, "articles">, content: nil, id: nil, inserted_at: nil, short_title: "lalalilala", slug: 457, title: nil, updated_at: nil}.
以下是我尝试创建链接的方法:
def link_to_article(conn, article_map) do
article = struct(%XX.YY.Article{}, article_map)
link article_map.short_title,
to: page_path(conn, :index, article),
class: "btn btn-default"
end
我有to_param的实现:
defimpl Phoenix.Param, for: XX.YY.Article do
alias XX.YY.Slug
def to_param(%{slug: slug, title: title}) do
"#{Slug.pad_slug(slug)}-#{Slug.slugify_title(title)}"
end
end
如果我将article_map
提供给链接,那么链接可以工作但很难看(地图成为查询字符串)。 article
强制使用to_param
并创建一个漂亮的网址,我缺少什么?
编辑,这是路由器声明:
get "/", PageController, :index
get "/:article", PageController, :index
我希望网址与qweqwe.com/padded_slug-article_title
在控制器中,我将索引定义为:
def index(conn, %{"article" => article_identifier}) do
[slug|_] = article_identifier |> String.split("-")
article = XX.YY.get_current_article(slug)
case article do
nil -> Phoenix.Controller.redirect(conn, to: "/")
article ->
render conn, "index.html",
articles: XX.YY.get_articles_for_menu!(),
current_article: article
end
end
def index(conn, _params) do
render conn, "index.html",
articles: XX.YY.get_articles_for_menu!(),
current_article: XX.YY.get_default_article!()
end
这段代码难看吗?
到目前为止所有路线:
page_path GET / QQ.PageController :index
user_path GET /users QQ.UserController :index
user_path GET /users/:id/edit QQ.UserController :edit
user_path GET /users/new QQ.UserController :new
user_path GET /users/:id QQ.UserController :show
user_path POST /users QQ.UserController :create
user_path PATCH /users/:id QQ.UserController :update
PUT /users/:id QQ.UserController :update
user_path DELETE /users/:id QQ.UserController :delete
article_path GET /articles QQ.ArticleController :index
article_path GET /articles/:id/edit QQ.ArticleController :edit
article_path GET /articles/new QQ.ArticleController :new
article_path GET /articles/:id QQ.ArticleController :show
article_path POST /articles QQ.ArticleController :create
article_path PATCH /articles/:id QQ.ArticleController :update
PUT /articles/:id QQ.ArticleController :update
article_path DELETE /articles/:id QQ.ArticleController :delete
page_path GET /:article QQ.PageController :index
调用堆栈:
(elixir) lib/enum.ex:1: Enumerable.impl_for!/1
(elixir) lib/enum.ex:116: Enumerable.reduce/3
(elixir) lib/enum.ex:1823: Enum.reduce/3
(XX) lib/QQ/router.ex:1: QQ.Router.Helpers.segments/3
(XX) lib/QQ/router.ex:1: QQ.Router.Helpers.page_path/3
(XX) lib/QQ/views/layout_view.ex:8: QQ.LayoutView.link_to_article/2
答案 0 :(得分:1)
您有两条路由指向同一个控制器/功能(PageController.index
)。路由器帮助程序函数仅为控制器/函数的第一个实例生成,这就是为什么在尝试将Article作为第三个参数传递时会出现错误的原因。
如果您未使用get "/", PageController, :index
路线,则删除该路线将解决错误。
如果您正在使用它,您必须在第二条路线上添加自定义名称,如下所示:
get "/:article", PageController, :index, as: :article_index
现在您可以使用article_index_path
生成路径:
article_index_path(conn, :index, article)