我刚刚意识到我的网站上很难找到错误。我经常使用Model.find从我的数据库中检索数据。
一年前,我合并了三个网站,导致需要处理大量重定向。为此,我在我的应用程序控制器中创建了一个" catch all" -functionality,如下所示:
around_filter :catch_not_found
def catch_not_found
yield
rescue ActiveRecord::RecordNotFound
require 'functions/redirections'
handle_redirection(request.path)
end
另外我在routes.rb
:
match '*not_found_path', :to => 'redirections#not_found_catcher', via: :get, as: :redirect_catcher, :constraints => lambda{|req| req.path !~ /\.(png|gif|jpg|txt|js|css)$/ }
重定向控制器具有:
def not_found_catcher
handle_redirection(request.path)
end
我不确定这些问题在这个问题上是否相关,但我想这更好。
我的实际问题
我经常使用Model.find从我的数据库中检索数据。让我们说我有一个带有这样的控制器的产品型号:
def show
@product = Product.find(params[:id])
@product.country = Country.find(...some id that does not exist...)
end
# View
<%= @product.country.name %>
这是我在我的应用程序的700多个地方使用的东西。我今天意识到的是即使找到了产品模型。调用Country.find()并找不到某些东西会导致RecordNotFound,从而导致404错误。
如果在{.find-search中找不到该国家/地区,我已经使我的应用程序符合@product.country = nil
的期望。我现在知道情况并非如此 - 它会创建一个RecordNotFound。基本上,如果我加载Product#show,我将得到一个404页,我希望得到500错误(因为@product.country = nil
和nil.name
不起作用)。
我的问题
我现在的大问题。我在我的应用程序中做错了,我应该总是将Model.find_by_id用于我的Country.find(...some id...)
之类的查询吗?这里的最佳做法是什么?
或者,问题在于我在应用程序控制器中的所有问题吗?
答案 0 :(得分:2)
回答你的问题:
我应该始终使用Model.find_by_id
如果您想按ID找到,请使用Country.find(...some id...)
。如果你想找到别的东西,请使用eg。 Country.find_by(name: 'Australia')
。 Rails 4中不再支持find_by_name
语法。
但是,这不是你的问题。
或者,问题在于我在应用程序控制器中的问题吗?
是的,这对我来说听起来像是一种痛苦的食谱。我不确定你具体做了什么,或者你的重定向的性质是什么,但基于我对你所做的事情的模糊感,这里是我和我的方式。 #39; d接近它:
您的Rails应用程序不应负责重定向您以前的网站/应用程序中的路由。这应该是您的网络服务器的责任(例如nginx或apache或其他)。
基本上,您希望列出要重定向的所有URL的大胖列表,以及要将其重定向到的位置,然后按照Web服务器的预期方式对其进行格式化,并配置您的Web服务器以执行重定向为了你。搜索eg&#34; 301重定向nginx&#34;或&#34; 301重定向apache&#34;找出有关如何设置的信息。
如果您有很多要重定向的网址,那么您可能希望使用代码生成列表(大多数逻辑应该已经存在于您的handle_redirection(request.path)
方法中)。< / p>
一旦您运行了该代码并生成了该列表,您就可以抛弃该代码,您的网络服务器将处理旧网站的重定向,并且您的rails应用程序可以愉快地继续,而不知道以前的站点/ URL,并且应用程序控制器中没有危险的catch-all逻辑。
答案 1 :(得分:1)
这是一种非常有趣的处理异常的方法......
在Rails中,您使用rescue_from
来处理控制器层上的异常:
class ApplicationController < ActionController::Base
rescue_from SomeError, with: :oh_noes
private def oh_noes
render text: 'Oh no.'
end
end
然而,Rails已经通过提供静态html页面来处理一些异常(其中包括ActiveRecord::RecordNotFound
)。你可以override with dynamic handlers。
然而,@ joshua.paling已经指出你应该在服务器级而不是你的应用程序中处理重定向。