Custom function in nested resources, not found

For this route:

resources "/articles", Admin.ArticleController do
  resources "/comments", Admin.CommentController do
    put "/test1", Admin.CommentController, :mark_as_ok
  end

This route gets found:

  admin_article_comment_path(@conn, :edit, @comment.article.id, @comment.id)

Whereas this throws a compilation error – not found:

  admin_article_comment_path(@conn, :mark_as_ok, @comment.article.id, @comment.id)

mark_as_ok exists in the CommentController .

Why error?

This works:

admin_article_comment_comment_path

Why double ‘comment’? How to make it single?

admin_article_comment_comment_path(@conn, :mark_as_ok, @comment.article.id, @comment.id)

Why double ‘comment’? How to make it single?

Do not nest the :mark_as_ok route within your comments resource. The second comment is there for the same reason the outer resource has article as part of its route helper function.

2 Likes

I don’t understand

resources "/articles", Admin.ArticleController do
  put "/comments/test1", Admin.CommentController, :mark_as_ok
  resources "/comments", Admin.CommentController 
end
1 Like

In that case it won’t contain “comment_id” in its url unlike previously

:wave:

resources "/articles", Admin.ArticleController do
  # try adding a :comment_id here
  put "/comments/:comment_id/test1", Admin.CommentController, :mark_as_ok
  resources "/comments", Admin.CommentController 
end

As for the double comment:

resources "/articles", Admin.ArticleController do # <- _article_
  resources "/comments", Admin.CommentController do # _comment_
    put "/test1", Admin.CommentController, :mark_as_ok # _comment_path
  end
end

You can also just rename it too:

resources "/articles", Admin.ArticleController do
  resources "/comments", Admin.CommentController do
    put "/test1", Admin.CommentController, :mark_as_ok, as: admin_article_comment
  end
end

And thus admin_article_comment_path(...) will work, or rename it as you wish (the system appends _path and _url to make the actual names).

1 Like

Too unlogical. Why does it work this way?

What do you expect the path to be called if you type something like

put "/comment", CommentController, :mark_as_ok

?

I expect comment_path/2.

What about

resources "/commens", CommentController

?

Again, I expect comment_path/2,3.

Combining these two macros we get each part in the generated path, which while in your case leads to duplication, it doesn’t make it illogical but rather consistent. If the default was to drop the route names from the generated path helpers when the routes are placed inside resources, it would lead to needless surprises.

And if I had “resources”?

Hmm? It has nothing to do with resources, setting an as: only defines the path/url helper names for that specific call (or on all calls of embedded sets). What error were you having?