如何优雅地检查对象和关联对象的存在?
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】:我会使用安全导航运算符 (&.
) 并编写如下内容:
<% @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】:
使用&&
(或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 面向对象--继承,实现,依赖,关联,聚合,组合
在 Django 中,如何优雅地将查询集过滤器添加到大型组或对象的所有成员?