Rails:将所有未知路由重定向到root_url

42

每当用户访问了错误的页面时,Rails 会展示 public 文件夹中的 404.html。不过,我只想将浏览器重定向到根目录页面,而不显示任何信息。因此,我尝试使用 globbing,但没有成功,它仍然展示 404 页面。这是我的路由文件中的一段代码:

# ...
map.root :controller => 'home', :action => 'home'
map.connect '*', :controller => 'home', :action => 'home'

有什么建议吗?谢谢大家!


我假设你有一个名为'home_controller'的控制器,其中包含一个名为'home'的动作,该动作类似于render :nothing => true? - jenjenut233
不是的。在主控制器中有一个主页操作,还有一个主页视图(home.html.erb)。 - Albus Dumbledore
5个回答

79
如果你的项目使用Rails 3,只需在routes.rb文件中添加这一行代码。
match '*path' => redirect('/')

补充:如果您使用的是Rails 4或5

match '*path' => redirect('/'), via: :get

或者

get '*path' => redirect('/')

你也可以使用 get 代替 match,这只是添加 via: :get 的速记方式。 - Peeja
8
请确保将此内容放在路由列表的底部。 - ahnbizcad
这似乎对于具有无效 ID 的有效路由不起作用(例如 root.com/articles/293,其中 293 是您的数据库中不存在的文章 ID)。 - ahnbizcad
1
那是因为路由已经匹配,这就是路由器关心的全部。您需要在控制器中进行额外的检查,以查看提供的ID是否对应文章存在。 - Almir Sarajčić
我想指出,在这个答案中,“or”不应该是代码块的一部分。应该是 match '*path' => redirect('/'), via: :get 或者 get '*path' => redirect('/') - GameKyuubi
显示剩余2条评论

21

就像Arkan的答案一样。有一点需要注意,如果不想在开发环境中出现这种行为,则可以执行以下操作 -

match '*path' => redirect('/')   unless Rails.env.development?

11

Rails 4-

(routes.rb)

您仍然可以使用简单的get方法来重定向所有未知路由。

  get '*path', to: 'home#index'
如果您希望为POST和GET请求提供路由,您仍然可以使用match,但Rails希望您通过via指定请求方法。
  match "*path" => "home#index", via: [:get, :post]  

记住routes.rb文件是按顺序执行的(匹配第一个符合提供路径结构的路由),因此将通配符放在匹配项的底部。


1
感谢您提醒将其放在底部。 - ahnbizcad
这还能用吗?在我的Rails 4应用中似乎没法工作。 - Jeremy Thomas
我在Rails 5中遇到了一个问题,其中get '*path',to:'searches#new'导致我的应用程序中所有上传的图像都出现406错误。 - tomb

9
似乎在 Rails 5.2 中存在一个 bug,即 active_storage 路由被 catchall 路由拾取,导致上传的图片链接无法正常工作。该问题已在 Github 上的 rails 存储库中报告,有人评论了以下补丁,直到新版本修复此 bug:
routes.rb 文件中,在最后一个 end 上面插入以下内容:
get '*all', to: 'application#index', constraints: lambda { |req|
    req.path.exclude? 'rails/active_storage'
  }

然后在应用程序控制器中添加:

def index
  flash.notice = 'No page found at that address'
  redirect_to root_path
end

2
此外,您可以在应用程序初始化后添加 catch-all 路由,如此处所述: https://github.com/rails/rails/issues/671#issuecomment-1780159 - Zoran Majstorovic
1
这个答案是在Rails 6中使用ActiveStorage的最佳方法。 - Sergio Gonzalez

1
你需要创建一个控制器来完成这个任务。
class RedirectsController 

  def index
    redirect_to root_url
  end
end

在你的路由中

map.connect '*', :controller => 'redirects', :action => 'index'

这个答案也适用于Rails 3吗? - Sam Wilder
也适用于 Rails 3。你只需要更改与匹配相关的行即可。请参阅路由指南中的 globing。 - shingara

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接