6

I have a model called Spaces which has different types of places... such as Bars, Restaurants, etc. It has the same columns, same, model, controller, etc. no fancy STI, I just have one field called Space_type which I would like to determine an aliased route.

Instead of domain.com/spaces/12345 it would be /bars/12345 or /clubs/12345

Currently I have:

  resources :spaces do
    collection do
      get :update_availables
      get :update_search
      get :autocomplete
    end
    member do
      post :publish
      post :scrape
    end
    resources :photos do
      collection do
        put :sort
      end
    end

    resources :reviews
  end

Also, Is there a way I can do this so that anytime I use the space_url it can figure out which one to use?

holden
  • 13,081
  • 21
  • 89
  • 157

2 Answers2

6

The routes are not a way to interact with your model directly. So, as long as you write a standard route, you can make things work. For instance, to make /bars/12345 and /clubs/12345 for your spaces_controller (or whatever the name of the controller is) , you can create routes like :

scope :path => '/bars', :controller => :spaces do
  get '/:id' => :show_bars, :as => 'bar'
end  

scope :path => '/clubs', :controller => :spaces do
  get '/:id' => :show_clubs, :as => 'clubs'
end  
Spyros
  • 41,000
  • 23
  • 80
  • 121
5
# routes.rb
match "/:space_type/:id", :to => "spaces#show", :as => :space_type

# linking
link_to "My space", space_type_path(@space.space_type, @space.id)

which will generate this urls: /bars/123, /clubs/1 ... any space_type you have

And it looks like STI wold do this job little cleaner ;)

UPD

Also you can add constraints to prevent some collisions:

match "/:space_type/:id", :to => "spaces#show", :as => :space_type, :constraints => { :space_type => /bars|clubs|hotels/ }

And yes - it is good idea to put this rout in the bottom of all other routes

You can also wrap it as a helper (and rewrite your default space_url):

module SpacesHelper
  def mod_space_url(space, *attrs)
    # I don't know if you need to pluralize your space_type: space.space_type.pluralize
    space_type_url(space.space_type, space.id, attrs)
  end
end
fl00r
  • 79,728
  • 29
  • 207
  • 231
  • wouldn't "/:space_type/:id", :to => "spaces#show", :as => :space_type interfere with all the rest of my controllers unrelated to spaces? – holden Apr 15 '11 at 10:01
  • No it won't. About STI, linking and routing check out: http://stackoverflow.com/questions/5246767/sti-one-controller/5252136#5252136 – fl00r Apr 15 '11 at 10:04
  • 2
    You need to ensure that "/:space_type/:id" goes below your other top level resource declarations in config/routes.rb for this to not interfere. Rails can always route itself, but if you declare a "resources :waffles" below the custom matcher, someone can navigate to "/waffles/1234" and it will route that to the spaces controller as a waffle type. – Patrick Robertson Apr 15 '11 at 11:53