Ruby on rails 如何处理此问题-NoMethodError vs NoRecordFound

Ruby on rails 如何处理此问题-NoMethodError vs NoRecordFound,ruby-on-rails,ruby,ruby-on-rails-3,Ruby On Rails,Ruby,Ruby On Rails 3,我只是想知道处理以下问题的最佳方法,因为互联网上似乎有关于这一点的相互冲突的信息。我的代码就是这样开始的 @merchant = Merchant.find_by_name(params[:merchant]) @products = @merchant.products.all.paginate(:page => params[:page]) 现在这很好,直到你点击了一个商家不存在的url,即/merchants/thisonedontextist/,这时我得到了以下错误: `unde

我只是想知道处理以下问题的最佳方法,因为互联网上似乎有关于这一点的相互冲突的信息。我的代码就是这样开始的

@merchant = Merchant.find_by_name(params[:merchant])
@products = @merchant.products.all.paginate(:page => params[:page])
现在这很好,直到你点击了一个商家不存在的url,即
/merchants/thisonedontextist/
,这时我得到了以下错误:

`undefined method `products' for nil:NilClass`
我明白为什么我会犯这个错误

因此,经过一点研究,我决定用一个砰(!)将我的代码更改为以下代码,这会引发一个NoRecordFound错误,因此它永远不会到达下一行,问题是,我现在遇到了一个丑陋的错误:

@merchant = Merchant.find_by_name!(params[:merchant])
@products = @merchant.products.all.paginate(:page => params[:page])
错误为:
ActiveRecord::RecordNotFound

所以在做了更多的研究之后,我做了以下工作,并将这些请求重定向到404

  def show
    @merchant = Merchant.find_by_name(params[:merchant])
    if !@merchant.nil?
      @products = @merchant.products.all.paginate(:page => params[:page])
    else
      redirect_to :status => 404
    end
  end
看起来很有效,但看起来很笨重。。。这里的最佳实践是什么

我只想让它显示一个类似
“对不起,没有类别存在”
的页面


p、 我是Rails新手,也许对于这个问题有一个非常明显的答案

使用bang版本是最好的方法。一个命名错误告诉我您没有正确处理应用程序工作流

此外,使用bang版本可以简化代码。 在生产中,
ActiveRecord::RecordNotFound
作为404保存。这意味着,当出现错误时,Rails将援救错误,并在默认情况下为您显示404错误页面和404状态代码

您可以简化代码

def show
  @merchant = Merchant.find_by_name!(params[:merchant])
  @products = @merchant.products.all.paginate(:page => params[:page])
end

使用bang版本是最好的方法。一个命名错误告诉我您没有正确处理应用程序工作流

此外,使用bang版本可以简化代码。 在生产中,
ActiveRecord::RecordNotFound
作为404保存。这意味着,当出现错误时,Rails将援救错误,并在默认情况下为您显示404错误页面和404状态代码

您可以简化代码

def show
  @merchant = Merchant.find_by_name!(params[:merchant])
  @products = @merchant.products.all.paginate(:page => params[:page])
end
控制器

  def show
    @merchant = Merchant.find_by_name(params[:merchant])
    @products = @merchant.products.all.paginate(:page => params[:page]) if @merchant
  end
在您的视图中/show.html.erb

if @merchant
  ...
  ...your code here
else
  <div>No such merchant</div>
end
if@merchant
...
…您的代码在这里
其他的
没有这样的商人
结束
控制器

  def show
    @merchant = Merchant.find_by_name(params[:merchant])
    @products = @merchant.products.all.paginate(:page => params[:page]) if @merchant
  end
在您的视图中/show.html.erb

if @merchant
  ...
  ...your code here
else
  <div>No such merchant</div>
end
if@merchant
...
…您的代码在这里
其他的
没有这样的商人
结束

正如@simone所说,您可以将代码简化为

def show
  @merchant = Merchant.find_by_name!(params[:merchant])
  @products = @merchant.products.all.paginate(:page => params[:page])
end
现在,当找不到@merchant时,会引发异常。幸运的是,rails提供了一个极好的解决方案,可以很好地处理异常

在控制器内部(或
应用程序控制器
中,如果希望使其成为通用的),您可以编写

rescue_from ActiveRecord::RecordNotFound, :with => :handle_not_found

def handle_not_found
  # either 
  flash[:error] = ... some appropriate error message ...
  redirect_to :root # or some relevant path
end

因此,在该方法中,您可以随心所欲地处理异常。

正如@simone所说,您可以将代码简化为

def show
  @merchant = Merchant.find_by_name!(params[:merchant])
  @products = @merchant.products.all.paginate(:page => params[:page])
end
现在,当找不到@merchant时,会引发异常。幸运的是,rails提供了一个极好的解决方案,可以很好地处理异常

在控制器内部(或
应用程序控制器
中,如果希望使其成为通用的),您可以编写

rescue_from ActiveRecord::RecordNotFound, :with => :handle_not_found

def handle_not_found
  # either 
  flash[:error] = ... some appropriate error message ...
  redirect_to :root # or some relevant path
end

因此,在该方法中,您可以根据自己的意愿执行任何处理异常的操作。

谢谢您的回答,尽管我确实需要“.all”否则会出现以下错误:未初始化的常量ActiveRecord::Calculations::Calculations\u选项so Simone,您是说当我将其部署到生产服务器时,此错误将默认为404吗?有没有办法在本地进行测试?ActiveRecord::RecordNotFound in MerchantsController#show无法找到名为xxxYes的商户。您甚至可以在您的计算机上测试它,但您需要运行生产环境或禁用
将所有请求视为本地
功能,当您通过localhost运行应用程序时,该功能会自动显示每个错误。如果您想确保,创建一个功能测试并使用它来验证功能。如何在本地投入生产?对不起,我是一个新手:(.我知道这有点像ENV=production。如果是这样,这只是Rails令人惊叹的另一个原因。谢谢你的回答,尽管我确实需要“.all”否则我会得到以下错误:未初始化的常量ActiveRecord::Calculations::Calculations\u OPTIONSSo Simone,你是说当我将此部署到生产服务器时,此错误将默认为404?是否有任何方法在本地测试此错误?ActiveRecord::RecordNotFound in MerchantsController#show无法找到具有na的商户me=xxxYes。您甚至可以在您的计算机上测试它,但您需要运行生产环境或禁用
将所有请求视为本地
功能,当您通过本地主机运行应用程序时,该功能会自动显示每个错误。如果您想确保,请创建功能测试并使用它验证该功能。如何输入into本地生产?抱歉,我是一个新手:(.我知道这类似于ENV=production。如果是这种情况,这只是Rails令人敬畏的另一个原因。抱歉,这是“clunk-o-matic”抱歉,这是“clunk-o-matic”