21
votes

Let's say I want to create a resources with adding a couple of custom actions to it, the analogue in rails is:

resources :tasks do
  member do
    get :implement
  end
end

Which will return me not only 7 standard routes, but 1 new:

GET /tasks/:id/implement

How can I do it in phoenix?

4

4 Answers

26
votes

I want to improve Dogbert's answer a little bit:

resources "/tasks", TaskController do
  get "/implement", TaskController, :implement, as: :implement
end

The only addition is as: :implement in the end of the route.

Thus you will get route named task_implement_path instead of ugly task_task_path.

18
votes

You can add a get inside the do block of resources.

web/router.ex

resources "/tasks", TaskController do
  get "/implement", TaskController, :implement
end

$ mix phoenix.routes

     task_path  GET     /tasks                     MyApp.TaskController :index
     task_path  GET     /tasks/:id/edit            MyApp.TaskController :edit
     task_path  GET     /tasks/new                 MyApp.TaskController :new
     task_path  GET     /tasks/:id                 MyApp.TaskController :show
     task_path  POST    /tasks                     MyApp.TaskController :create
     task_path  PATCH   /tasks/:id                 MyApp.TaskController :update
                PUT     /tasks/:id                 MyApp.TaskController :update
     task_path  DELETE  /tasks/:id                 MyApp.TaskController :delete
task_task_path  GET     /tasks/:task_id/implement  MyApp.TaskController :implement
11
votes

Here is another solution:

scope "/tasks" do
  get "/:id/implement", TasksController, :implement
  get "/done", TasksController, :done
end
resources "/tasks", TasksController

The implement action has a member route and the done action has a collection route.

You can get the path for the former with this function call:

tasks_path(@conn, :implement, task)

Note that you should place the resources line after the scope block. Otherwise, the Phoenix recognizes /tasks/done as the path for show action.

0
votes

It looks like a collection route would have to be:

get "tasks/implement", Tasks, :implement # collection route

I don't think phoenix has member / collection resource routes like rails does.

I found this link were they talk about collection routes a little and give an example like the one I included above:

https://github.com/phoenixframework/phoenix/issues/10