【问题标题】:How do I elegantly check for presence of both the object and associated objects?如何优雅地检查对象和关联对象的存在?
【发布时间】:2019-06-21 00:32:59
【问题描述】:

我有一个实例变量@tally_property,如果该对象上有photos,我想循环浏览照片并显示它们。

所以我的代码 sn-p 看起来像这样:

<% if @tally_property.photos.present? %>
   <% @tally_property.photos.each_with_index do |photo, index| %>

问题是基于上述,如果@tally_property 为nil,那么整个第一行都会抛出错误。

那么有没有我可以做的不笨重的“零”检查,即我不想在主要对象和关联上做if @tally_property.nil?,并且优雅和红宝石和rails-esque ?

【问题讨论】:

  • 你有 & (孤独的操作符),但它算作 nil-chek,所以,如果 @tally_property 为 nil,你真的需要返回其他东西,因为它不会响应 @ 987654326@。你可以为此引入一个装饰器。

标签: ruby-on-rails ruby ruby-on-rails-3.2


【解决方案1】:

我会使用安全导航运算符 (&amp;.) 并编写如下内容:

<% @tally_property&.photos&.each_with_index do |photo, index| %>
  ... 
<% end %>

【讨论】:

    【解决方案2】:

    在 Ruby 2.3.0+ 中,您可以使用安全导航运算符:

    @tally_property&.photos
    

    ActiveSupport 有一个.try 方法,可以在旧版本的 ruby​​ 中用于相同目的:

    @tally_property.try(:photos)
    

    您可以添加一个简单的条件来安全地遍历集合:

    <% (@tally_property.try(:photos)||[]).each_with_index do |photo, index| %>
    
    <% end %>
    

    Rails 4 添加了ActiveRecord::Relation#none 并更改了行为,以便关联始终返回ActiveRecord::Relation。所以写起来完全可以接受:

    <% @tally_property.try(:photos).try(:each_with_index) do |photo, index| %>
    
    <% end %>
    

    升级您的应用后。或者你可以使用部分渲染:

    <%= render partial: 'photos', collection: @tally_property.photos if @tally_property %>
    

    这消除了编写迭代的需要。

    【讨论】:

    • @tally_property.try(:photos) 将在@tally_property nil 的情况下返回 nil,不是吗?如果是这样,它还会强制您添加一个额外的try
    • try(:photos)||[]) 或者 try(:photos), []) ?
    • @YuriyVerbitskiy nil.try(:foo, "bar") == nil
    • @YuriyVerbitskiy try(:photos)||[]) 是语法错误。
    • @YuriyVerbitskiy try(:photos), []) 实际上也是我的第一个参数,因为如果第二个参数是默认值,那将是非常合乎逻辑的。 .try 实际上像 Object.send 一样工作——剩余的参数被传递给方法。 "foo|bar".try(:split, "|") == ["foo", "bar"].
    【解决方案3】:

    使用&amp;&amp;(或and,他们各有各的甜蜜点)。

    暂时把它从 Erb 中拿出来,我一般会这样写:

    if @tally_property and @tally_property.photos.present?
    

    取决于photos 我可能会使用:

    if @tally_property and @tally_property.photos
    

    或许:

    if @tally_property and not @tally_property.photos.empty?
    

    有时我会使用临时变量:

    if (photos = @tally_property && @tally_property.photos)
      photos.each #…
    

    那种东西。

    我会推荐这一集的 Ruby Tapas,And/Or 以便更长时间(但仍然很快)观看。

    【讨论】:

      【解决方案4】:

      还有一种方法,只需选择与此 tally_property 关联的所有照片:

      示例:

      Photo.joins(:tally_property).each_with_index 做 |照片,索引|

      【讨论】:

      • 但是那些照片不是属于@tally_property的,而是属于一个tally属性的所有照片,不是吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 2011-09-26
      • 1970-01-01
      • 2019-05-24
      • 1970-01-01
      • 1970-01-01
      • 2011-12-24
      相关资源
      最近更新 更多