0

Few day ago, I started using Phoenix 1.3, and everything was fine until I started adding a new action in the controller.

Router.ex

 resources "/users", UserController, only: [:show] do
    resources "/events", EventController do

      get "/:id", EventController, :join, as: :join
    end
  end

Event_controller.ex

def join(conn, %{"event_id" => id}, current_user) do
#some stuff..
conn
  |> put_status(:ok)
  |> put_flash(:info, "You just joined Event")
  |> redirect(to: page_path(conn, :index, current_user))
end

then in my show template: /event/show.html.eex

<%= link "To list", to: user_event_path(@conn, :index, @event.user) %>
<%= if @current_user.id != @user.id do %>
  <h1> <%= @user.name %> Event ! </h1>
  <h3> <%= @event.title %></h3>
  <p><%= @event.description %></p>
  <p><%= @event.location %></p>
  <p><%= @event.price %></p>
  <%= link "Join", to: user_event_path(@conn, :join, @current_user.id,
  @event.id), class: "btn btn-default btn-xs" %>

I tried to do something like that in other projects with Phoenix 1.2 and its work, but it wasn't exactly the same code.

Can someone help me to understand why it is not working...

Btw sorry for my English!

The Error saying :

No function clause for Eventoma.Web.Router.Helpers.user_event_path/4 
and action :join. The following actions/clauses are supported:
user_event_path(conn_or_endpoint, :create, user_id, opts \\ [])
user_event_path(conn_or_endpoint, :delete, user_id, id, opts \\ [])
user_event_path(conn_or_endpoint, :edit, user_id, id, opts \\ [])
user_event_path(conn_or_endpoint, :index, user_id, opts \\ [])
user_event_path(conn_or_endpoint, :new, user_id, opts \\ [])
user_event_path(conn_or_endpoint, :show, user_id, id, opts \\ [])
user_event_path(conn_or_endpoint, :update, user_id, id, opts \\ [])
    (phoenix) lib/phoenix/router/helpers.ex:299: Phoenix.Router.Helpers.raise_route_error/5
Afshin Moazami
  • 2,092
  • 5
  • 33
  • 55
elchemista
  • 23
  • 5

2 Answers2

2

You can run mix phx.routes to see which routes are available.

If you run this on the router you provided, you will see:

$ mix phx.routes
           user_path  GET     /users/:id                            MyApp.Web.UserController :show
     user_event_path  GET     /users/:user_id/events                MyApp.Web.EventController :index
     user_event_path  GET     /users/:user_id/events/:id/edit       MyApp.Web.EventController :edit
     user_event_path  GET     /users/:user_id/events/new            MyApp.Web.EventController :new
     user_event_path  GET     /users/:user_id/events/:id            MyApp.Web.EventController :show
     user_event_path  POST    /users/:user_id/events                MyApp.Web.EventController :create
     user_event_path  PATCH   /users/:user_id/events/:id            MyApp.Web.EventController :update
                      PUT     /users/:user_id/events/:id            MyApp.Web.EventController :update
     user_event_path  DELETE  /users/:user_id/events/:id            MyApp.Web.EventController :delete
user_event_join_path  GET     /users/:user_id/events/:event_id/:id  MyApp.Web.EventController :join

The bottom one is the join route:

user_event_join_path  GET     /users/:user_id/events/:event_id/:id  MyApp.Web.EventController :join

There are :user_id, :event_id and id all present.

What you actually want for the this to work:

<%= link "Join", to: user_event_path(@conn, :join, @current_user.id, @event.id), class: "btn btn-default btn-xs" %>

Is the following router:

resources "/users", UserController, only: [:show] do
  resources "/events", EventController
  get "/events/:id", EventController, :join
end

Which results in the following:

user_event_path  GET     /users/:user_id/events/:id        MyApp.Web.EventController :join

As an aside, if you are making any changes to your data (which the verb :join suggests) then you should perhaps use a PUT request (based on this answer https://stackoverflow.com/a/630475/219743)

Gazler
  • 83,029
  • 18
  • 279
  • 245
-1

So playing around I understand, was doing completly wrong stuff! As Phoenix is one big plug that modify my conn, the answer is something like this:

router.ex:

post "/events/:id", EventController, :join

wich then bring as to event_controller.ex :

def join(conn,  %{"id" => id}, current_user) do
     conn
     |> put_flash(:info, "You just joined Event")
     |> redirect(to: page_path(conn, :index))
end

and will be called from template as /template/show.html.exx:

<%= link "Join", to: user_event_path(@conn, :join, 
                   @current_user, @event),
                   method: :join,
                   class: "btn btn-danger btn-xs" %>

so i hope if some one get same errors and can't figured out what is going on.

elchemista
  • 23
  • 5