user1795547
user1795547

Reputation: 21

Routing in rails - When to route to a crud method and when to route with the given parameter

I am in need of a little help regarding routing in rails. Traditionally if I have a route in routes.rb

resources:categories

it will match www.website.com/categories/id were id is an integer. But what happens if I wanted to route to a specific user or category like so:

www.example.com/categories/apple

instead of the traditional:

www.example.com/categories/4

I currently have these two lines in my routes.rb

match 'categories/:name' => 'categories#show'

resources :categories

so www.example.com/categories/apple will route to the show method in the categories controller correctly.

but

What if I want to create a new category? Here's the problem

www.example.com/categories/new

will route to the show method, and will not route to the new method

I can place an if statement in the show method checking is params[:name] == new, but I feel that there must be a better way to solve this problem.

My end goal is to route based on the string of the category (apple) and not based on it's ID (4) but also be able to create, update, and destroy a category.

Any tips?

Thanks!

Upvotes: 0

Views: 165

Answers (3)

ksu
ksu

Reputation: 608

I think the most simple way to do this your way is to define a route before your

match 'categories/:name' => 'categories#show'

like this:

match 'categories/new' => 'categories#new'

match 'categories/:name' => 'categories#show'

the order matters.

Upvotes: 0

rewritten
rewritten

Reputation: 16435

As @pdoherty926 says in the comment, you could use FriendlyId. If you want to manage it manually, you don't have to overwrite the routes, just put the needed code in the :show action:

class CategoriesControllers < ...
  ...

  def show
    if /^\d+$/ =~ params[:id]
      # ... normal workflow for integer id
    elsif /soe_regexp_that_matches_names>/
      # ... do your thing with names
    else
      raise 404
    end
  end

  ...
end

Upvotes: 0

joseramonc
joseramonc

Reputation: 1931

you can pass a name as a parameter, for example you can try

link_to category_path(category.name) instead of link_to category_path(category)

and it will go to categories#show in controller, the route will look like example.com/categories/categoryName, in the show action of your cateogries controller, params[:id] will have the name, you'll need something like

Category.find_by_name params[:id] instead of Category.find params[:id]

Hope this helps you.

Upvotes: 0

Related Questions