2

I have several publications (posts) which belong to a type and a category, and I want to have routes like this :

  • /some-type-slug
  • /some-type-slug/some-category-slug
  • /some-category-slug

which all point to publications#index where I do all the filtering

As long as I tried only with type and optional category it worked just fine with :

scope ':type', :constraints => lambda{|req| PublicationType.all.map(&:slug).include?(req.params[:type].singularize) } do
  match 'new'          => 'publications#new'
  match '(/:category)' => 'publications#index'
end

But when I added the same bit of code about categories, and I try to go to "/some-category" it ended just not working :

match ':category' => 'publications#index', :constraints => lambda{|req| Category.all.map(&:slug).include?(req.params[:category].singularize) }

leads to :

NoMethodError in PublicationsController#index

undefined method `singularize' for nil:NilClass

Parameters:

{"type"=>"some-category-slug"}

Ok so the NoMethodError is thrown because params[:category] is nil. And it is because the :category part of the url had just been "stolen" by the previous route definition : params[:type] is set with the :category part of the url.

So I wonder if this is a bug in the Rails router or if I'm just trying to push it a bit too far. And if I am I'd like to know what are my other options to achieve the same result.

Thanks !

Jeremy F.
  • 1,346
  • 12
  • 30

1 Answers1

3

I understand what you want to do, but I think you're on dangerous ground, trying to match routes like this.

What you're doing could also be achieved like so.

match ":slug" => "slugs#show"

class SlugsController

  def show
    if type = PublicationType.find_by_slug(params[:slug])
      ...
    elsif category = Category.find_by_slug(params[:slug])
      ...
    else
      render_404
    end
  end
end

(see this answer for a great discussion of how to render a 404)

It might seem over the top but this is effectively what you're doing anyway.

You're just doing it with lambdas in your routes file.

I suggest you rethink your url strategy.

/cat/some-slug
/type/some-slug

are not so bad.

Community
  • 1
  • 1
Matthew Rudy
  • 16,724
  • 3
  • 46
  • 44
  • You are totally right I shouldn't do such thing. And actually I did change my code since the time I posted my question. BUT I think this weird behavior still is a **bug in Rails**. What do you think ? Should I file a ticket about this ? – Jeremy F. Dec 19 '11 at 16:51