Ruby on Rails and standard mod_rewrite - ruby-on-rails

I've got an old application written in PHP and now I am replacing it by new RoR app. The old application has links like "this-is-seo-title,n123.html". In htaccess there is a rule which is translating those links to news.php?id=123.
Now when I setup RoR app, links are in "RoR way" (:controller/:action/:id). It's cool and nice, but in Google I've got about 50k indexed subpages. I don't want get this indexed subpages broken so now here is a question:
Can I create new rules inside htaccess file which will be translating "this-is-seo-title,n123.html" links to /news/123 ?
I didn't deploy app yet and I don't have access to environment with passenger module, so I can't test it myself.

I don't think it's necessary to use htaccess. If you are going rails, then do it with the rails helpers. I think this should work in your routes.rb:
match 'this-is-seo-title,n:id.html' => 'news#show'
That route will invoke the NewsController and the show action with 123 as an :id parameter. Was that what you where looking for?
Edit:
For Rails 2
map.connect 'this-is-seo-title,n:id.html', :controller => 'news', :action => 'show'
At least I think that will work in Rails 2. I don't have any environment up and running atm to test with. Let me know if it doesn't work.

Related

RoR routing error in "hello world"

I'm trying to learn web-dev and decided to learn ruby on rails. I'm doing the first tutorial from "Agile Web Development with Rails". I've seen there are quite a few search results on google, but all the recommendation is "to restart the server", which does not help my case.
So, I started webrick and generate controller Say with these code:
def hello
end
and then I added hello.rhtml, which has some basic html with message "Hello from rails".
When i type in browser: http://localhost:3000/say/hello
I get : No route matches [GET] "/say/hello"
I tried to restart webrick, doesn't work. The bug-name suggest it has to do with routes, i've got two versions of the book, none of them have the steps to alter the routes.rb and within routes.rb i have commented-out stuff and class definition.
Does anyone know what should i do?
I'm guessing is a problem in your routes file. You need to define what you want rails to do (which controller+action you want to be perform) when that URL is received. So, do the following:
match 'say/hello', :to => "say#hello"
This will tell rails that when a URL with say/hello is received, the hello action of the controller say has to be performed.

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.

Blank page when navigating to http://localhost:3000/say/hello

I'm new to Ruby on Rails and am doing my first tutorial and am running the latest version of rails 3 and ruby 1.9.2. After creating my controller and navigating to http://localhost:3000/say/hello I'm receiving a blank page. I do see the Welcome to Rails message when I just go to http://localhost:3000. I've done some Google searches and people have similar problems but there is no clear fix. I've never really worked with MVC before so the concept of routing is fairly new to me.
Below is my controller:
class SayController < ApplicationController
def hello
end
def goodbye
end
end
My view:
<h1>Say hello to Rails!</h1>
You should delete the public/index.html file as that will mess with your routing and display by default. Have you set up your routes already, and what is the exact location and filename of the template?
You will need something like in your config/routes.rb file to correctly route that url to your template/view:
match '/say/hello' => 'say#hello'
First delete the index.html file from your public folder. Then, go to the app/views and check the views for the say controller. You should have a hello.html.erb.
The answer to your particular question was answered already by Bitterzoet, but I thought you might want some alternative learning resources.
I'm not sure which tutorial you're starting with, but I find it odd that they're not using RESTful routes. You can find out what routes you have set up at the moment by going to the console and typing "rake routes". If you would like a different tutorial, I recommend the one here:
http://www.wiki.devchix.com/index.php?title=Rails_3_Curriculum
I'd also recommend http://railsforzombies.org/ as a good first-time rails experience.
A fun general line to add to config/routes is:
match ':controller(/:action(/:id(.:format)))'
While developing, this will allow you to display the controller/action in address bar for ALL controller/action/id.format etc.
Like Bitterzote wrote, if controller is "say" and action is "hello", http://localhost:3000/say/hello .
If you use controller "say" and action "move", http://localhost:3000/say/move .
I've found this route to be very useful during development, but change this if you launch your application! (Rails warns: "Note: This route will make all actions in every controller accessible via GET requests.")

github url style

I wanted to have users within my website to have their own URL like http://mysite.com/username (similar to GitHub, e.g. my account is http:// github. com/sr3d). This would help with SEO since every profile is under the same domain, as apposed to the sub-domain approach.
My site is running on Rails and Nginx/Passenger. Currently I have a solution using a bunch of rewrite in the nginx.conf file, and hard-coded controller names (with namespace support as well). I can share include the nginx.conf here if you guys want to take a look.
I wanted to know if there's a better way of making the URL pretty like that.
(If you suggest a better place to post this question then please let me know)
Cheers,
Alex
Place this line right at the end of the routes.rb file, ( So that this doesn't interfere with other controller routes )
map.connect "/:username", :controller=> "users", :action => "show"
in users_controller, use the following line to fetch the user
#user = User.find_by_username(params[:username])
I don't think this would require any nginx magic or url rewrites.
HTH

Resources