Mohamad
Mohamad

Reputation: 35349

Routes with optional params in Rails

I'm trying to setup a route that looks like this: acme.com/posts/:category/:status. Both :category and :status are optional. I wrote many variations, but none worked:

resources :posts do
  match '(/:category)(/:status)', to: 'posts#index', as: 'filter', on: :collection
end

# Category Links
link_to "Questions", filter_posts_path(:questions)
link_to "Suggestions", filter_posts_path(:suggestions)

# Status Links
link_to "Published", filter_posts_path(params[:category], :published)
link_to "Draft", filter_posts_path(params[:category], :draft)

The idea is to be able to 1) filter by category, 2) filter by status, and 3) filter by both category and status if both are available. The current setup has also broken my /posts/new path, always redirecting to posts#index.

Upvotes: 6

Views: 4550

Answers (4)

Moin Haidar
Moin Haidar

Reputation: 1694

I had this variation and it seems working fine:

  namespace :admin do
    resources :posts, :except => [:show] do
      collection do
        get "/(:category(/:status))", to: "posts#index", as: "list", :constraints => lambda{|req|
          req.env["PATH_INFO"].to_s !~ /new|\d/i
        }
      end
    end
  end

= CONTROLLER=admin/posts rake route

list_admin_posts GET    /admin/posts(/:category(/:status))(.:format)                 admin/posts#index

Upvotes: 2

spas
spas

Reputation: 1934

You could try something like this:

match '/filter/*category_or_status' => 'posts#index', as: 'filter'

With this you can build your own filter path. Then you could parse params[:category_or_status] in your controller and get the category or status if they are given.

Upvotes: 0

felipeclopes
felipeclopes

Reputation: 4070

Do this works for you?

resources :posts do
  collection do
    match '/:category(/:status)', to: 'posts#index', as: 'filter'
    match '/:status', to: 'posts#index', as: 'filter'
  end
end

Hope at least it helps!

Upvotes: 0

rthbound
rthbound

Reputation: 1343

You can use the more RESTful resources :posts (in config/routes.rb) and send the params in the query string.

With that approach, all parameters are optional and you're not limited to using predefined parameters.

Upvotes: 1

Related Questions