New to Rails. Doubt in Big URL Routing - ruby-on-rails

I have just started learning ruby on rails. I have a doubt wrt routing.
Default Routing in Rails is :controller/:action/:id
It works really fine for the example lets say example.com/publisher/author/book_name
Could you tell me how do you work with something very big like this site
http://www.telegraph.co.uk/sport/football/leagues/premierleague/chelsea/
Could you let me understand about the various controllers, actions, ids for the above mentioned url and how to code controller, models so as to achieve this.
Could you suggest me some good tutorials when dealing with this big urls.
Looking forward for your help
Thanks in advance
Gautam

This is achieved using nested resources (read or google for "rails restful routes". In your case it could look something like this:
map.resources :sports do |sport|
sport.resources :leagues do |league|
league.resources :team
# probably more nested routes for members or sponsors or whatever...
end
end
end
You can also view your defined routes with rake task:
$ rake routes
This RailsCasts episode also covers some basics on restful routing with nested resources.

The routing engine can handle URLs of arbitrary size. It all depends on what your spec is. For that it would be:
map.sport_league_team '/sport/:sport/leagues/:league/:team'
What controller you route that to is the important part. This is then called like:
<%= link_to("Chelsea", sport_league_team_path('football', 'premierleague', 'chelsea') %>
You can always examine what routes are defined with:
rake routes

The Rails Routing from the Outside In guide is a good place to start.

Related

Rails URL and Path Helpers in Engines Like Spree

I'm trying to use some URL and/or path helpers in my Rails 4 Engine views such as resource_url or resource_path. These engines are configured a bit differently than the typical --mountable tutorial out there. In fact, they more closely resemble how Spree does it, without the Spree::ENGINE_NAME namespace.
Like Spree's architecture, I'm attempting to create core engine that my other engines depend on. For example, my backend engine's routes.rb file looks like this:
Core::Engine.add_routes do
# Check to see if the request comes in on a subdomain
# The Subdomains class passed into constraints()
# is a class defined in lib/subdomain.rb
constraints(Subdomain) do
match '/manage' => "manage#index", :via => [:get]
end
end
In a view inside my backend engine, I'd like to be able to use some URL/path helpers to do something like this:
<%= link_to manage_path, manage_path %>
This doesn't work, because I'm drawing the routes on the core engine. So, I must use
<%= link_to core_engine.manage_path, core_engine.manage_path %>
Spree somehow gets around this, but I'm not sure how. For example, in backend/app/views/spree/admin/products/index.html.erb:
<%= link_to product.try(:name), edit_admin_product_path(product) %>
Notice, the edit_admin_product_path, but no mention of this actually being drawn on the core engine.
Any ideas?
We get around this by drawing all the routes on the core engine using add_routes which exists for reasons I won't go into here because it's a long tangent. Necessary evil for this kind of work, though.
The isolate_namespace method within Core::Engine scopes everything to the spree namespace. If you're inside a controller that's been drawn underneath the Spree::Core::Engine routes and you want to reference a route for another controller also drawn under that route then you can leave off the spree. prefix on the routing helper.
If you're routing to a different engine, then you will need to have the prefix: main_app. or whatever.
The Engines Guide explains this in greater detail, and I'd recommend reading that.

What's the "Rails Way" to create route helpers to other hosts?

My app consists of two rails servers with mostly different concerns sitting behind a reverse proxy. Let's call them Server1 and Server2. Occasionally, Server1 needs to render a link to a url on Server2. Is there a good way to use Rails route helpers for this? Specifically in Rails 2? I came up with this:
ActionController::Routing::Routes.draw do |map|
# other routes omitted
map.with_options(:host => 'server2.example.com') do |add|
# create a named route for 'http://server2.example.com/thingies'
add.server2_thingies '/thingies', :controller => 'fake'
# create a named route for 'http://server2.example.com/thingies/combobulate'
add.enhance_server2_thingies '/thingies/combobulate', :controller => 'fake'
# create a named route for 'http://server2.example.com/mabobs/combobulate'
add.enhance_server2_mabobs '/mabobs/combobulate', :controller => 'fake'
# etc..
end
end
So then I can use server2_thingies_url and such in my views. This works, but it makes me feel like a bad person because there is no FakeController and I certainly have no intention of routing requests to it. I considered making helper methods and placing them in app/controllers/application_controller.rb, but a colleague made the argument that it is best to keep all route helpers in routes.rb, so things like rake routes will be accurate, for instance. Is there a better way?
I think I'd make a counter-argument to your colleague: if you're having to dirty up routes.rb with a "FakeController", then your rake routes is still not going to be accurate. In fact, I'd say that this is exactly the kind of thing that a helper was meant to help: it's taking logic that belongs purely in the view (link generation), and removing it from your view templates. Helpers are also easier to maintain and tweak.
Another advantage to the helper style is that if and when it's time to upgrade to Rails 3.x, the less hackish your routes.rb file is, the happier you will be - and that I can attest to from experience. :)
I'd just pass in :host to your foo_path or foo_url calls.
Seems cleaner than messing around with a FakeController

Using Ruby on Rails link_to to link to controller action

I'd just started toying around with Ruby on Rails and had come across an issue with linking to another action in a controller from a particular view. I am almost certain it's an issue (or lack of code) in my routes.rb file, but I think I'm misunderstanding exactly how this file works & what I have to do. I've got a solution but pretty sure it's not the "best way" to do it.
I have one controller called home with two actions, index (which is the default) and newbill. Inside index.html.erb I have:
<h1>Home View</h1>
<%= link_to "new", :controller => "home", :action => "newbill" %>
However I was getting a routing error:
No route matches {:controller=>"home", :action=>"newbill"}
Doing rake routes gives me the following:
root / {:controller=>"home", :action=>"index"}
I then (following some Googling) added this code to routes.rb
match 'home/newbill' => 'home#newbill', :as => :newbill
And then in my index.html.erb I've got this:
<%= link_to "Name", newbill_path %>
And now this works as expected. My questions however are:
Why does this work? What exactly is going on behind the scenes?
Surely this is not the best way to do it? Adding another match 'home/newbill'... for every controller / action I want to link to seems a rubbish way of doing things.
I really like Ruby, but struggling a bit with this aspect of Rails...routing in general is messing up my head a bit I think!
Any help is much appreciated :D
Thanks,
Jack
I guess the first time your code didn't work because your home controller is defined as a resource.
If you define a controller as a resource in routes.rb file it will support only 7 standard methods (according to REST architecture):
index
new
create
show
edit
update
destroy
If you need any more custom routes you should add them manually, say in your case 'newbill', may go as:
resources :home do
collection do
get :newbill
end
end
But as per my understanding, your newbill method should go to bills controllers new, method not in the home controller.
You are right, Rails routes are little bit confusing (at least for me), but once you understand you can do lots of cool stuff.
Read here for the Rails official routes documentation:
http://guides.rubyonrails.org/routing.html.
You should check out the Rails Routing guide. A read through will help you understand what is going on behind the scenes.
This works becuase rails filters every request through the router looking for a match. This enables you to define custom routes such as domain.com/post when the path is actually blog#post. Prior to rails 3, a catch-all route was the last route in the routes file. This allowed you to define a controller and action and it would just work. I'm on my iPad and not near any projects, so I can't verify it, but I think that route is still there in rails 3.1, it just needs to be umcommented.

Generating an object's absolute url without html markup

Is there a method like "full_url" such that #comment.full_url or full_url_for(#comment) returns "http://www.host.com/comments/id" where www.host.com is the default host domain and id is #comment.id. Or, if not, what would be an elegant way to generate this url string?
I'm pretty new at Rails, most of the methods I've learned insert the tag and other markup.
url_for is not helping because I can't do something like the following:
url_for(#comment, {:only_path => false})
I've spent way too much time trying to figure this out. It came down to either hacking or asking for the right way on SO. Here I am.
If you are setting up your routes correctly in your config/routes.rb file then you should have access to named routes in your controller and in your views. Which should mean that all you should need to do is:
comment_path(#comment)
Or for the full url
comment_url(#comment)
To see a list of all of the routes from the command line, you can type rake routes from the project root. Welcome to rails! Here is a good resource for rails 3 routing: http://guides.rubyonrails.org/routing.html
some additional resources via Railscasts:
http://railscasts.com/episodes/231-routing-walkthrough
http://railscasts.com/episodes/232-routing-walkthrough-part-2

Ruby on rails path helpers

I know this is a minor issue, but why, if you use scaffolding in RoR, can you use lines like 'new_model name here_path' in link tags, but without using scaffolding, I get a NameError? For example, I have a simple address book app that uses basic CRUD operations. I am a RoR beginner but wanted to build an app without scaffolding and these kind of things don't seem to work. I compared my config/routes.rb and app/helpers/* with those in a scaffolded app and they are no different. What am I missing?
One way to check your routes and paths is to run:
rake routes
It outputs all your routes and paths.
Scaffolding sets up resource routes in the routes.rb file. The resource routes are what give you the path and url helpers. When you don't use scaffolding the routes aren't added, you must do it by hand.
Resource Routes can be added like so:
map.resources :models
where :models is the plural name of one of your models.

Resources