5
votes

I have a 'transaction' model, controller and view, which I created with rails generate. Now I need to add a single custom route of /transactions/history to my application to be handled by a controller def history:... end and render history.html.erb

So added this line in my routes.rb:

get '/transactions/history', to: 'transactions#history', as: 'transactions_history'

And this in my transactions_controller.rb:

def history
    @transactions = Transaction.all
end

and created a history.htmk.erb in transactions->views

I also see this line when calling rake routes:

transactions_history GET    /transactions/history(.:format)                 transactions#history

But when I request localhost:3000/transactions/history in my browser, it gives me the following error:

Couldn't find Transaction with 'id'=history

(Because I have this line in my controller)

before_action :set_transaction, only: [:show, :edit, :update, :destroy])

and I also see this line in logs:

Request info

Request parameters  
{"controller"=>"transactions", "action"=>"show", "id"=>"history"}

My full routes: routes.rb My full errors: error logs Why it is calling the 'show' action in my transaction controller?

2
Can you post your full routes.rb file? And a full transcript of what you see when you rake routes?moveson

2 Answers

5
votes

In your routes.rb, the rails scaffold generator should have added a resources :transactions. This will generate 7 routes for you, one of them being /transactions/:id which corresponds to the show action in TransactionsController.

Rails matches the routes in the order defined in routes.rb and will call the controller action of the first matching route.

I am guessing in your case you defined get '/transactions/history', to: 'transactions#history', as: 'transactions_history' below resources :transactions. As you are passing /transactions/history, this is calling the show action with the :id matching history.

To fix this, there are 2 solutions:

First, move your custom route above the resources :transactions.

Or extend the resources declaration and remove your custom route like so:

resources :transactions do
  collection do
    get :history
  end
end
1
votes

It is because your route is conflicting with the default resource route, specifically GET transactions/:id.

resources :transactions do
  get :history, on: :collection
end

http://guides.rubyonrails.org/routing.html#adding-collection-routes

You can also try:

  1. Switching the order that your routes are defined, or
  2. Changing your custom route so it does not conflict, e.g. instead of /transactions/history try /transaction_history or something else.