Topic: How to remove the name of the controller in the URL?

Hello,

I have a Rails 2.3 application, with a single REST controller named 'articles' and its RESTful route "map.resources :articles".

I can access to some article via the URL http://www.example.com/articles/1.

I would like to get rid of the name of the controller in the URL, ie to access to the article via the URL http://www.example.com/1.

I could do that with
map.connect '/:id', :controller => "articles", :action => "show"

But I would like to get rid of the name of the controller for all my actions, for instance: http://www.example.com/1/edit instead of http://www.example.com/articles/1/edit. Is there a simple/concise way to achieve this?

I tried to use the :as option like this but without success (idem with the :controller option):

map.resources :articles :as => ""
or
map.resources :articles :as => "/"

Thanks by advance smile

Florent

Re: How to remove the name of the controller in the URL?

If you wanna do it for the root of the app, you can get away with

map.connect ':id', :controller => :articles, :action => :show

Last edited by moger777@hotmail.com (2009-04-14 21:58:18)

Re: How to remove the name of the controller in the URL?

Can I ask why you want to do that?

Re: How to remove the name of the controller in the URL?

@moger: thanks for your answer. It looks like the solution I gave in my first post. I was looking for a concise way to get rid of the controller name for all its actions, maybe it is not possible.

@cherring: for a cosmetic reason, just to have shorter and cleaner URLs.

Re: How to remove the name of the controller in the URL?

@Flo23
I'm looking for the same solution. Let me know if you find it.
Thanks! smile

Re: How to remove the name of the controller in the URL?

If it's just cosmetic then I think that you are beating your head against a wall for no reason, you surely need to have something in your url instead of just a number, how else will your application know which controller you are requesting???

The only way I can think of to implement this idea is to do your entire site with AJAX, that what you could request any controller you want, but the user would never see the url, and then it would just be http://mysite.com, can't get much shorter than that.

I don't really like this idea though, it's a lot of extra work for basically no reason, and then also how would a user be able to directly refer to a url? They couldn't really, I'd suggest really questioning how important this is.

Re: How to remove the name of the controller in the URL?

In my case for example, I have a controller called "general" that deals with usual static pages, such as about, home and contact. So the default routing for these pages is of the following format:

host/general/about
host/general/home

But I don't want the users see "general" in the URL. I want them to type host/about to get the corresponding page.

I found out that you can use the named routes(http://guides.rubyonrails.org/routing.html#named-routes) to do something like that. You have to declare them as following:

map.about 'about', :controller => 'general', :action => 'about'

But you have to do it for every action in that controller, which could end up in a lot of lines. I was after figuring out a general way of declaring route for a controller, that would affect every action in the same way.

Hope it makes sence.

Re: How to remove the name of the controller in the URL?

cherring wrote:

If it's just cosmetic then I think that you are beating your head against a wall for no reason, you surely need to have something in your url instead of just a number, how else will your application know which controller you are requesting???

I have only one controller in my application.

Re: How to remove the name of the controller in the URL?

moger777@hotmail.com wrote:

If you wanna do it for the root of the app, you can get away with

map.connect ':id', :controller => :articles, :action => :show

Thanks I was searching for exactly this.

Re: How to remove the name of the controller in the URL?

Is there really no solution for this? For all practical purposes, everything in my site is routed through a single controller. This means that no matter what you do on the site it looks like localhost/menu_items/this_page and localhost/menu_items/that_page.

All I want to do is tell it to do exactly the same thing that map.resources does, except to not include menu_items in the path, essentially extending my domain name with hideous back-end logic.

I can just hear the mockery now:
josh: Hey, check out my website, over at mydomain.com
josh's facetious friend: Oh, you mean mydomain.com/menu_items ? Yeah, I saw it already.

I can do what andredurao has done, and use lots of map.connects (and I would have already) but then I can't keep my named routes. I've looked around, asked on irc, read all of http://guides.rubyonrails.org/routing.html, and even tried to understand vendor/rails/actionpack/lib/action_controller/resources.rb but I can't figure out how to name these routes the same way that rails does, and I don't want to go through the hundreds of files I've written, converting helper methods to static links.

Can someone at the very least show me how I would have to define my named routes in order to get the same functionality that map.resources gives? Then I can just edit the url matchers myself and run some tests to ensure it all works correctly.

Thanks to anyone willing to help, sorry if I came off a little irritated, I've been at this for hours.

Last edited by joshua_cheek (2009-07-19 13:36:27)

Re: How to remove the name of the controller in the URL?

I had the same problem while re-factoring an old app to use resources instead of the messy hashes. Try creating a new initializer file like "config/initializers/empty_resources.rb" and add the following segment of code:

module ActionController
  module Resources
    class Resource
      def path_segment_with_slash
        path_segment.blank? ? '' : "/#{path_segment}"
      end

      def path
        @path ||= path_prefix.to_s + path_segment_with_slash
      end

      def member_path
        @member_path ||= "#{shallow_path_prefix}#{path_segment_with_slash}/:id"
      end

      def nesting_path_prefix
        @nesting_path_prefix ||= "#{shallow_path_prefix}#{path_segment_with_slash}/:#{singular}_id"
      end
    end
  end
end


Check out your new routes with: rake routes

The original Resource class always adds an initial '/' to your paths, this little bit of code modifies the class so that the slash is only added if the path segment (:as) is not empty. This of course means you can only have one empty resources, and the map.root must appear before!

I've only tested this with Rails 2.3.2, but it should in theory work with other versions.

Good luck!
sam

--
planetaki.com/sam

Re: How to remove the name of the controller in the URL?

@samlown - Very helpful code.  Thanks!  In case anyone else needs a routes.rb example, this is how to remove the controller name in the url for one resource, at least...

map.resources :users, :as => ''

If you combine this with a 'to_param' method in your 'Post' model, you can have very nice looking urls...

<%= url_for @user %> 

would create '/swards' (instead of /users/swards, for example).

By the way - I ended up doing the following:

map.resources :users, :as => '', :only => [:show, :edit, :update, :destroy]
map.resources :users, :only => [:index, :new, :create]

This was to avoid some urls that I didn't want to create (such as '/new') and this makes it so it doesn't conflict with the root, as samlown points out.

Re: How to remove the name of the controller in the URL?

I think that's a best solution... than :as => ''

  map.resources :cities, :only => 'index'
  map.city ':id', :controller => 'cities', :action => 'show'