【问题标题】:Rails nil errors - any way to stop them?Rails nil 错误 - 有什么方法可以阻止它们?
【发布时间】:2013-02-18 11:50:29
【问题描述】:

在过去的 6 个月里,我一直在学习 Rails。我认为这很棒!

但是,我的应用程序遇到的 99% 的错误都是零错误。我要么试图显示一个为零的字段,要么外键指向已删除的记录。

我在很多地方都有这种类型的代码:

        <% if location.parent != nil %>
          <td><%= location.parent.name %></td>
        <% else %>
          <td></td>
        <% end %>

      <% if location.client_id != nil %>
        <td><%= location.client.client_name %></td>
      <% else %>
        <td></td>
      <% end %>

我真的希望 Rails 在字段为 nil 时显示空白!或者,设置一个错误的闪光灯并仍然显示页面。相反,页面炸弹。在 Heroku 上,您会收到“抱歉,出了点问题......”

有没有办法更好地处理空白字段?有没有更好的方法来编写上述代码?是否有一些我不知道的 Rails 设置?是否有 gem 可以处理这些类型的错误?

【问题讨论】:

    标签: ruby-on-rails-3


    【解决方案1】:

    你真的应该放一些foreign key constraintsafter_destroy methods on your associations。这将阻止您的数据库进入不一致的状态。

    但除了重构之外,您还应该查看 ActiveSupport 以及它对 ruby​​ 所做的各种添加。见http://guides.rubyonrails.org/active_support_core_extensions.html

    我认为对您有帮助的任何对象都可以使用三种方法:

    • blank? - 如果对象为 nil、empty?、false 和其他条件,则返回 true。请参阅the documentation 以获得更好的解释。
    • present? - 如果对象不为零,不为空,则返回 true?或真的。请参阅the documentation 以获得更好的解释。
    • try(:foo) - 尝试在对象上调用方法 foo,如果对象为 nil,则返回 nil。请参阅the documentation 以获得更好的解释。

    这样你的示例代码可以是:

    <td><%= location.parent.try(:name) %></td>
    <td><%= location.parent.try(:client_name) %></td>
    

    我真的建议你看看为什么你期望一个对象不是 nil。 Foreign key constraints 在您的迁移中,after_destroy hooks for your associations 将对此有所帮助。

    【讨论】:

    • 谢谢 - 我会进一步调查您的建议。
    • 我认为您还应该解释安全导航操作员的好处。而不是try
    • 公平评论 - 虽然当我回答这个问题时 ruby​​ 2.3 没有发布(发布前两年!)。 TBH 我个人尽量避免使用try&amp;.,因为这会导致代码中的保护条款不足或忽略得墨忒耳法则。
    【解决方案2】:

    不是 Rails 修复,但您可以使用面向对象设计的 NullObject 模式来重构您的代码以不同方式处理“nil”。该模式基本上意味着您为一个对象创建一个 null/nil 类,该对象在它为 nil 时进行处理。它有一些缺点:需要维护一个额外的类,并且当您添加可能为 nil 的新方法时,您必须记住编辑 null 类。好处是它将条件句移出视图。

    这里有一篇关于这个主题的好博文: http://robots.thoughtbot.com/post/20907555103/rails-refactoring-example-introduce-null-object

    另一个建议是将条件句从您的视图中移出并放入助手中。助手是包含视图逻辑的简单模块。我在视图中遇到了所有逻辑视图,这让视图代码很快变得一团糟。

    【讨论】:

      猜你喜欢
      • 2022-06-15
      • 2011-04-08
      • 1970-01-01
      • 1970-01-01
      • 2011-04-25
      • 1970-01-01
      • 2013-02-07
      • 2011-12-02
      • 1970-01-01
      相关资源
      最近更新 更多