存在样式尝试可能属性的方法

时间:2017-05-04 22:07:42

标签: ruby-on-rails ruby

如果有方法有条件地调用方法,是否有更像红宝石的方式?

目前在做:

count = if thing.respond_to?(:sometimes_available)
  thing.sometimes_available 
else
  thing.do_expensive_query_to_get_available
end

例如,有时我会查询集合并选择额外的属性

Thing.join(:authors)
  .select('things.*, count(authors.id) as sometimes_available')
  .group('things.id')

做以下事情会很棒:

thing.presence(:sometimes_available) || thing.expensive

2 个答案:

答案 0 :(得分:1)

您可能正在寻找的功能可能是ActiveSupport#try

try实际上会返回nil,即使该对象没有响应您发送它的方法。

然后您可以将代码重写为:

thing.try(:sometimes_available) || thing.expensive

在幕后,它与你正在做的事情做了类似的逻辑

def try(*a, &b)
  if a.empty? || respond_to?(a.first)
    # omitted for simplicity
    a.public_send(*a, &b)
  end
end

答案 1 :(得分:0)

将上一个答案标记为正确,但想澄清一下:

Rails4向Object#try引入了一个monkeypatch,它也完成了我上面解释的内容

指向提交的链接: https://github.com/rails/rails/commit/99ea1a875b06feb4346869f371e2a57a2cc0a0fc