cancel
Showing results for 
Search instead for 
Did you mean: 

How to redirect to a 404 in Rails?

I'd like to 'fake' a 404 page in Rails. In PHP, I would just send a header with the error code as such:

 

header("HTTP/1.0 404 Not Found");

How is that done with Rails?

MurbiesWalto
Member
4 REPLIES 4

You could also use the render file:

render file: "#{Rails.root}/public/404.html", layout: false, status: 404

Where you can choose to use the layout or not.

Another option is to use the Exceptions to control it:

raise ActiveRecord::RecordNotFound, "Record not found."

More you can check here:

https://gist.github.com/AhmedNadar/b450fd65eda9c4afb8e04e28f1348af6  /omeglzechat

 

JamesHimmerla
Member

Don't render 404 yourself, there's no reason to; Rails has this functionality built in already. If you want to show a 404 page, create a render_404 method (or not_found as I called it) in ApplicationController like this:

def not_found
  raise ActionController::RoutingError.new('Not Found')
end

Rails also handles AbstractController::ActionNotFound, and ActiveRecord::RecordNotFound the same way.

This does two things better:

1) It uses Rails' built in rescue_from handler to render the 404 page, and 2) it interrupts the execution of your code, letting you do nice things like:

  user = User.find_by_email(params[:email]) or not_found
  user.do_something!

without having to write ugly conditional statements.

As a bonus, it's also super easy to handle in tests. For example, in an rspec integration test:

# RSpec 1

lambda {
  visit '/something/you/want/to/404'
}.should raise_error(ActionController::RoutingError)

# RSpec 2+

expect {
  get '/something/you/want/to/404'
}.to raise_error(ActionController::RoutingError)

And minitest:

assert_raises(ActionController::RoutingError) do 
  get '/something/you/want/to/404'
end

mod mini militia
ZackHarry
Member

To return a 404 header, just use the :status option for the render method. If you want to render the standard 404 page you can extract the feature in a method. If you want the action to render the error page and stop, simply use a return statement. LiteBlue

Aidan69
Member

Hey, I just stumbled upon your website, and I think this is one of the finest things I have read on the internet so far. The way you explained everything from scratch and gradually built the momentum is literally what everyone should do when writing about something. Since your blog has already captured my attention.

Regards: