Topic: 404 redirect

HI there,
this is my first post on this forum so I hope I make a good impression.  I I have found it help full alredy.

Ok so I can do this super easy in php, (but I want to do it in Ruby). What I have is a site that has been up and running on an ASP CMS taht formated all the urls as index.asp=page1, index.asp=page2 (you get the idea) they have decided that the way to go is to have a RoR cms installed by me and that is all good, I belive that Eribim CMS will do nicely. 
The problem is that the Serch engines and other people have book marked pages and indexed them.
What I need to make is a program that will act as a 404 error page that will look up the request, check the data base for the old page name, and if it is found redirect them to the new page and signall and http200.  If it is not found they would get a 404 page.
any sugestions as to where I should start.  it seems to me that thisa may even be able to use in the fron end as a ruby script but i cant find any site that have a human description of ruby functions.

JOsh

since, forum sigs  are a good way to have a soap box, here I go.
A BBCode WYSIWYG would be a great addition to this site.

Re: 404 redirect

You should actually be using 301 redirects (permanent) for stuff like this, so search engines transfer your old page's rankings to the new pages.

If your RoR app is running on Apache you can perform these redirects in .htaccess:

Redirect Permanent old/path/to/file.html /new/file

There are ways to do it in Rails, but if you have Apache and just a handful of URLs to redirect it's probably better to edit .htaccess instead. smile

vinnie - rails forum admin

Re: 404 redirect

I guess one of the things I really need to know are the ruby equivalant of
$_SERVER["REQUEST_URI"] & $_SERVER["HTTP_REFERER"]
Are there Super globals in ruby?

since, forum sigs  are a good way to have a soap box, here I go.
A BBCode WYSIWYG would be a great addition to this site.

Re: 404 redirect

request URI:

<%= request.request_uri %>

vinnie - rails forum admin

Re: 404 redirect

thanx vin,
but it is a large site w/ a few hundred pages. I need more then a .htaccess file. Becasue it has to be updateable but the client.
JOsh

since, forum sigs  are a good way to have a soap box, here I go.
A BBCode WYSIWYG would be a great addition to this site.

Re: 404 redirect

You can create a catch-all route in your config/routes.rb file like this:

ActionController::Routing::Routes.draw do |map|
  map.connect ':controller/:action/:id'
  map.connect '*path', :controller => 'some_controller', :action => 'some_action'
end

The assigned controller and action will be triggered if a controller wasn't found (the first :controller/:action/:id route wasn't triggered). You can grab the path using params[:path] in the assigned action and then compare it to the database and redirect appropriately. Does that work for you?

Railscasts - Free Ruby on Rails Screencasts

Re: 404 redirect

ryanb wrote:

You can create a catch-all route in your config/routes.rb file like this:

ActionController::Routing::Routes.draw do |map|
  map.connect ':controller/:action/:id'
  map.connect '*path', :controller => 'some_controller', :action => 'some_action'
end

The assigned controller and action will be triggered if a controller wasn't found (the first :controller/:action/:id route wasn't triggered). You can grab the path using params[:path] in the assigned action and then compare it to the database and redirect appropriately. Does that work for you?

So ryan what if the page that is being redirected to is not a controller?  the cart is now a php zen cart.  Should I wrap the page in a controller?  what if there is a static html file? will this be able to redirect there?

<rant>OK forgive me, I am still trying to learn RoR and doing practical work seemed better then doing so program from a book that I would never use seemed to be the way to go.  I really consider RoR to be where I want to go but have been at it for months (on and off) and have not been able to pick up on it.  I am just not finding it very intuitive.</rant>

Ru

since, forum sigs  are a good way to have a soap box, here I go.
A BBCode WYSIWYG would be a great addition to this site.

Re: 404 redirect

sanguis wrote:

So ryan what if the page that is being redirected to is not a controller?  the cart is now a php zen cart.  Should I wrap the page in a controller?  what if there is a static html file? will this be able to redirect there?

If you use redirect_to it will be a normal HTTP 302 redirect which will trigger a new request, so it will be just like someone typed that URL in the browser in the first place so static files and whatever else should work fine. You may want to look into using a 301 permanent redirect for this though.


sanguis wrote:

<rant>OK forgive me, I am still trying to learn RoR and doing practical work seemed better then doing so program from a book that I would never use seemed to be the way to go.  I really consider RoR to be where I want to go but have been at it for months (on and off) and have not been able to pick up on it.  I am just not finding it very intuitive.</rant>

Understandable. One thing to keep in mind is that Rails is very opinionated in how it wants you to do things. If you go against the grain you will have many problems with Rails and it will seem far from intuitive. Part of the learning curve of Rails is learning how it wants you to do something and doing it that way instead of your own way. It wasn't until I said "okay, I'll try it this Rails way" that I understood why Rails is so great. It turns out that the Rails way was so much better than my way too.

If there's a specific area you're having trouble with, post a new topic on these forums and maybe we can help.

Railscasts - Free Ruby on Rails Screencasts

Re: 404 redirect

ryanb wrote:

If there's a specific area you're having trouble with, post a new topic on these forums and maybe we can help.

well here is what I am thinking, if you would not mind. if I post a php script that does what I need it to do and if you could translate it in to RoR, or even ruby scripting it would help me learn.  I am able to understand completed code more then I am snippets.  I think that is part of my problem w/ rails, all I see is a little in this file and a little and the other file. it is very hard(for me) to see the big picture.

//assume database connection made/ forgive the use of globals
$page = $_SERVER['HTTP_REFERER'];
$query mysql_query('SELECT new_page FROM pages WHERE old_page="' . $page . '"');
if (mysql_num_rows($query) == 1){
  $new_page = mysql_fetch_row($query);
  header(HTTP/1.1 302 Found);
  header(location:$new_page);
} else {
  header(HTTP/1.1 404 Not Found);
  echo "no page here. blah blah blah";
}

I know it is quick and I know it is not all that clean there but you get the idea.  I figure that w/ a language as strong as ruby it should not be hard to do the same.

since, forum sigs  are a good way to have a soap box, here I go.
A BBCode WYSIWYG would be a great addition to this site.

Re: 404 redirect

As I'm sure you know, in Rails each database table is mapped to a model. This helps keep code organized if you have logic which pertains only to that model. Since Page doesn't really have any logic though, just a blank class is fine:

# in app/models/page.rb
class Page < ActiveRecord::Base
end

Next we need a controller to handle the request. I'll just call this PageController

# found in app/controllers/page_controller.rb
class PageController < ActionController::Base
  def unrecognized
    page = Page.find_by_old_page(request.request_uri)
    if page
      redirect_to page.new_page
    else
      render :file => "#{RAILS_ROOT}/public/404.html", :layout => false, :status => 404
    end
  end
end

You also need to set up the routes.rb to map all unknown requests to this controller and action:

ActionController::Routing::Routes.draw do |map|
  map.connect ':controller/:action/:id'
  map.connect '*path', :controller => 'page', :action => 'unrecognized'
end

That's untested, but I think it will work.

The reason rails has so many files is to aid in the DRY (do not repeat yourself) principle. The code inside a model can be called from any page/request so it doesn't have to be repeated all over the place. In this case the model doesn't have any logic specific to itself, but most models do.

Railscasts - Free Ruby on Rails Screencasts

Re: 404 redirect

the above program is certainly able the redirect to a 404(but that is because I am going to pages that don't exist).
but I not redirecting all.
I am testing on a web-brick server though does it respond to the same commands as Apache?

since, forum sigs  are a good way to have a soap box, here I go.
A BBCode WYSIWYG would be a great addition to this site.

Re: 404 redirect

sanguis wrote:

the above program is certainly able the redirect to a 404(but that is because I am going to pages that don't exist).
but I not redirecting all.

Sorry I don't understand. What's not working specifically?

sanguis wrote:

I am testing on a web-brick server though does it respond to the same commands as Apache?

It behaves the same unless there is some external apache file (such as a .htaccess file) which handles redirecting. Web brick would ignore any apache-specific configuration file such as that.

Railscasts - Free Ruby on Rails Screencasts

13

Re: 404 redirect

I've used code like this in the past but for some reason, placing it as the last route in my routes map gives me a:

write_recognition': can't convert Symbol into String (TypeError)

What I really want is for all 404's and 500's to raise an exception so I can catch them using the (way cool) exception notification plugin by Jamis Buck.

Any thoughts?

Thanks

ryanb wrote:

You can create a catch-all route in your config/routes.rb file like this:

ActionController::Routing::Routes.draw do |map|
  map.connect ':controller/:action/:id'
  map.connect '*path', :controller => 'some_controller', :action => 'some_action'
end

The assigned controller and action will be triggered if a controller wasn't found (the first :controller/:action/:id route wasn't triggered). You can grab the path using params[:path] in the assigned action and then compare it to the database and redirect appropriately. Does that work for you?

Re: 404 redirect

cwd wrote:

I've used code like this in the past but for some reason, placing it as the last route in my routes map gives me a:

write_recognition': can't convert Symbol into String (TypeError)

Hmm, I haven't experienced this error before. Perhaps it is something specific to your project. Can you paste the stack trace?

cwd wrote:

What I really want is for all 404's and 500's to raise an exception so I can catch them using the (way cool) exception notification plugin by Jamis Buck.

I'm not certain exactly how the plugin works, but shouldn't this already be happening for 500 errors as they are exceptions? I'm not sure why you'd want to be notified on 404 errors, but you could raise an ActiveRecord::RecordNotFound error instead of rendering a 404 page.

Railscasts - Free Ruby on Rails Screencasts

15

Re: 404 redirect

The stack trace is at the bottom. The way the plugin works is to trap 404s and 500s and grab a stack trace, then email it to me. It's really pretty cool. So here's a 404 I generated and as you can see, it is recognized as a RoutingError, but the plugin's rescue_action_in_public is not getting a crack at it. Do I want email on all 404s? I've done this for a number of sites and it's revealed a few subtle bugs in my code, but more often it reveals a case where some partner set up their link to our site incorrectly.

Thanks

ActionController::RoutingError (Recognition failed for "/zoo"):
    /vendor/rails/actionpack/lib/action_controller/routing.rb:545:in
`recognition_failed'
    /vendor/rails/actionpack/lib/action_controller/routing.rb:535:in
`recognize!'
    /vendor/rails/railties/lib/dispatcher.rb:38:in `dispatch'
   
/usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel/rails.rb:73:in
`process'
    /usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:551:in
`process_client'
    /usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:550:in
`process_client'
    /usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:636:in
`run'
    /usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:636:in
`run'
    /usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:625:in
`run'
    /usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:956:in
`run'
    /usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:955:in
`run'
   
/usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/bin/mongrel_rails:127:in
`run'
   
/usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel/command.rb:199:in
`run'
    /usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/bin/mongrel_rails:235
    /usr/local/bin/mongrel_rails:18

Re: 404 redirect

Hmm, can't really tell from that. sad

Your could try posting your routes file, but I don't know if that will help either. I can't duplicate your problem so I'm not sure what it is.

Railscasts - Free Ruby on Rails Screencasts

17

Re: 404 redirect

Probably not worth your time. It's an evil interaction between the version of edge this app is running and essentially everything else. Upgrading rails fixes the routing problem but blows up engines. So, unless I go through Rails releases backwards until engines succeeds then test the routing, I'm out of luck. But... the most recent big fix to Rails was a security update, so I think it's pretty important that engines work with it.

18

Re: 404 redirect

I wish I had something definitive, but the cure for this problem was to back off edge to Rel_1-1-6. My understanding is that some serious refactoring is taking place right now and it is affecting a code that dives down into the internals. Engines is one such area and evidently Jamis's plugin was another.

Re: 404 redirect

I hae to say that I have broken down.  I am going w/ a php front end back by an ajax_scaffold admin panel.  thank you ryan for your attempts to help w/ this issue.  I will continue to struggle w/ trying to figure out the methodoligy of RoR programing on other projects that are more simple CRUD stuff before trying to do any thing w/ sever commands.
JOsh

since, forum sigs  are a good way to have a soap box, here I go.
A BBCode WYSIWYG would be a great addition to this site.