mattC
mattC

Reputation: 373

Ruby on Rails - routing to a new page

I would like to create a new route that leads to the url '../coins/:id/events/pending-events' however my new route is leading to '..coins/:coin_id/events/:event_id/pending-events' when I do this. What am I doing wrong here and how can I fix this?

routes.rb

resources :coins do
  ...
  resources :events do
    get 'pending-events', to: 'events#pending'
    member do
      put "like", to: "events#upvote"
      put "dislike", to: "events#downvote"
    end
  end
  ...
end

event_controller.rb

...
def pending
  @events = Event.where(coin_id: @coin.id).order("created_at DESC")
end
...

Upvotes: 0

Views: 86

Answers (2)

jvillian
jvillian

Reputation: 20253

I suggest you do:

resources :coins do 
  resources :events do
    collection do 
      get :pending
    end
    member do
      put "like", to: "events#upvote"
      put "dislike", to: "events#downvote"
    end
  end
end

Which will give you:

pending_coin_events GET    /coins/:coin_id/events/pending(.:format)             events#pending
    like_coin_event PUT    /coins/:coin_id/events/:id/like(.:format)            events#upvote
 dislike_coin_event PUT    /coins/:coin_id/events/:id/dislike(.:format)         events#downvote
        coin_events GET    /coins/:coin_id/events(.:format)                     events#index
                    POST   /coins/:coin_id/events(.:format)                     events#create
     new_coin_event GET    /coins/:coin_id/events/new(.:format)                 events#new
    edit_coin_event GET    /coins/:coin_id/events/:id/edit(.:format)            events#edit
         coin_event GET    /coins/:coin_id/events/:id(.:format)                 events#show
                    PATCH  /coins/:coin_id/events/:id(.:format)                 events#update
                    PUT    /coins/:coin_id/events/:id(.:format)                 events#update
                    DELETE /coins/:coin_id/events/:id(.:format)                 events#destroy
              coins GET    /coins(.:format)                                     coins#index
                    POST   /coins(.:format)                                     coins#create
           new_coin GET    /coins/new(.:format)                                 coins#new
          edit_coin GET    /coins/:id/edit(.:format)                            coins#edit
               coin GET    /coins/:id(.:format)                                 coins#show
                    PATCH  /coins/:id(.:format)                                 coins#update
                    PUT    /coins/:id(.:format)                                 coins#update
                    DELETE /coins/:id(.:format)                                 coins#destroy

No need to specify to: and pending_coin_events_path reads nicely.

Personally, I would do:

resources :coins do 
  resources :events do
    collection do 
      get :pending
    end
    member do
      put :upvote
      put :downvote
    end
  end
end

Which will give you:

pending_coin_events GET    /coins/:coin_id/events/pending(.:format)             events#pending
  upvote_coin_event PUT    /coins/:coin_id/events/:id/upvote(.:format)          events#upvote
downvote_coin_event PUT    /coins/:coin_id/events/:id/downvote(.:format)        events#downvote
        coin_events GET    /coins/:coin_id/events(.:format)                     events#index
                    POST   /coins/:coin_id/events(.:format)                     events#create
     new_coin_event GET    /coins/:coin_id/events/new(.:format)                 events#new
    edit_coin_event GET    /coins/:coin_id/events/:id/edit(.:format)            events#edit
         coin_event GET    /coins/:coin_id/events/:id(.:format)                 events#show
                    PATCH  /coins/:coin_id/events/:id(.:format)                 events#update
                    PUT    /coins/:coin_id/events/:id(.:format)                 events#update
                    DELETE /coins/:coin_id/events/:id(.:format)                 events#destroy
              coins GET    /coins(.:format)                                     coins#index
                    POST   /coins(.:format)                                     coins#create
           new_coin GET    /coins/new(.:format)                                 coins#new
          edit_coin GET    /coins/:id/edit(.:format)                            coins#edit
               coin GET    /coins/:id(.:format)                                 coins#show
                    PATCH  /coins/:id(.:format)                                 coins#update
                    PUT    /coins/:id(.:format)                                 coins#update
                    DELETE /coins/:id(.:format)                                 coins#destroy

I like that better because:

  1. You're doing less typing
  2. Your action and paths are parallel
  3. Symbols are (IMO) prettier and subject to fewer typos

But, that's just me.

Upvotes: 0

darkcode
darkcode

Reputation: 938

Just add on: :collection to your route e.g:

  resources :coins do
    ...
    resources :events do
      get 'pending-events', to: 'events#pending', on: :collection
      member do
        put "like", to: "events#upvote"
        put "dislike", to: "events#downvote"
      end
    end
    ...
  end

More info: https://guides.rubyonrails.org/routing.html#adding-collection-routes

Upvotes: 1

Related Questions