1

I have an ecommerce site in Rails 4 where the product listing routes are based on 'resources listings'. This makes the listing show pages routes as /listing/:id. I want to include the product name in the route and make it be /listing/:id/:name - how would I do this.

I saw the friendlyid gem but I'd prefer doing this without a gem, if there is a simple way.

Here is listings route block:

  resources :listings do
        collection do
          post 'import'
          get 'search'
          get 'delete_all'
        end
   resources :orders, only: [:new, :create, :update, :show]
  end

Per Jorge's answer below, I added a get '/:name' => 'listings#show' but when I do rake routes, I get an error saying 'Could not find listing without an ID' and I still see the original route /listings/:id pointing to listings#show.

Update: When I paste the new route as above, the default routes when I click on a product is still /listings/:id. However, when I type in the new route /listings/:id/:name (e.g. listings/324/testlisting) I get an error as below:

Started GET "/listings/324/brand" for 127.0.0.1 at 2014-10-29 12:55:35 -0700
Processing by ListingsController#show as HTML
  Parameters: {"listing_id"=>"324", "name"=>"brand"}
Completed 404 Not Found in 1ms

ActiveRecord::RecordNotFound (Couldn't find Listing without an ID):
  app/controllers/listings_controller.rb:189:in `set_listing'

The 'set_listing' method just finds the listing based on the id. here is part of the listings controller.

  before_action :set_listing, only: [:show, :edit, :update, :destroy]

  def show
  end

  def set_listing
    @listing = Listing.find(params[:id])
  end
Moosa
  • 3,126
  • 5
  • 25
  • 45

1 Answers1

0

This is what you are looking for:

Rails3 Routes - Passing parameter to a member route

http://guides.rubyonrails.org/routing.html#nested-resources

resources :listing do
  get '/:name', to 'listings#whatever'
end

EDIT:

Does your routes look like these?

  resources :listings do
    get '/:name', :to => 'listings#show'
    collection do
      post 'import'
      get 'search'
      get 'delete_all'
    end
    resources :orders, only: [:new, :create, :update, :show]
  end

EDIT 2:

I recomend creating a new method:

def show_by_name
   @listing = Listing.find_by(name: params[:name])
   render action: 'show'
end

And use it on the route:

get '/:name', :to => 'listings#show_by_name'
Community
  • 1
  • 1
Jorge de los Santos
  • 4,583
  • 1
  • 17
  • 35