如何优雅地检查对象和关联对象的存在?

Posted

技术标签:

【中文标题】如何优雅地检查对象和关联对象的存在?【英文标题】: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@。你可以为此引入一个装饰器。 【参考方案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属性的所有照片,不是吗?

以上是关于如何优雅地检查对象和关联对象的存在?的主要内容,如果未能解决你的问题,请参考以下文章

Python 面向对象--继承,实现,依赖,关联,聚合,组合

对象不再存在后如何销毁与对象关联的数据?

如何优雅地使用命令行设置windows文件关联

在 Django 中,如何优雅地将查询集过滤器添加到大型组或对象的所有成员?

如何区分SQL SEVER 2000中的角色、权限、对象、用户之间的关联?

如果对象存在,则渲染关联对象