【问题标题】:Is there a benefit to Rails' ".present?" method?Rails 的“.present”有什么好处吗?方法?
【发布时间】:2019-12-14 03:39:08
【问题描述】:

在 Ruby on Rails 中,两者之间是否有区别:

if obj
  # ...
end

和:

if obj.present?
  # ...
end

似乎他们做同样的事情,不使用.present? 将有助于使代码行更短并且可能更清洁。我知道.present?blank? 是相反的,但我们是否应该在尝试确定一个对象是否“真实”时始终使用它?

是否存在某种性能差异?

【问题讨论】:

  • 也许吧,但我真的不需要知道 nil、empty、blank、present 之间的区别。我只是问在测试真实性时是否值得在对象上调用.present?
  • present? 存在性能成本,因为添加了额外的调用层,无论它是否重要,您都可以测试 with a benchmark。但我确实发现 Rails 新手使用它太多了 - 特别是在您只是检查变量是否已定义(不是 nil)的情况下。

标签: ruby-on-rails


【解决方案1】:

他们根本不做同样的事情。

在 Ruby 中,除了 nilfalse 之外的所有内容都是真实的。与其他流行动态语言中的类型转换 schenigans 相比,这非常合理。

irb(main):003:0> !!""
(irb):3: warning: string literal in condition
=> true
irb(main):004:0> !!0
=> true
irb(main):005:0> !![]
=> true
irb(main):006:0> !!{}
=> true
irb(main):007:0> !!Object.new
=> true
irb(main):008:0> !!nil
=> false
irb(main):009:0> !!false
=> false

present?presence 是 ActiveSupport 的一部分,可用于测试 nil 和 false,但在处理用户输入时实际上更有用:

irb(main):010:0> "".present?
=> false
irb(main):011:0> [].present?
=> false
irb(main):012:0> {}.present?
=> false

present?presence 被那些不想先学习 Ruby 的 Rails 初学者广泛使用。如果您只想检查是否发送了参数或是否设置了变量,只需使用隐式真值检查 (if foo) 或 foo.nil?

虽然 .present? 可用于 ActiveRecord 集合,但还有更多惯用正确的选择,例如 any?none?

【讨论】:

    【解决方案2】:

    #present? 方法做得更多,如果字符串是真实但空的字符串(即 ""),它也会返回 false

    这很有用,因为您的表单可能会返回空字符串而不是 nils。

    您也可以使用#presence,这是一种仅当值为#present? 时才返回值的有用方法

    name = params[:name].presence || 'ardavis'
    

    如果params[:name] 是一个空字符串并且您没有使用#presence,则上述方法将不起作用

    【讨论】:

    • 但如果我知道我的对象不是字符串,那么就不需要.present?,对吧?如果我做了obj = MyModel.find(some_id),那么我知道它要么是 nil,要么是 MyModel 的一个实例,对吧?
    • @ardavis find 永远不会返回 nil(尽管find_by 会)。如果find 失败,它将引发ActiveRecord::ResourceNotFound
    • 对不起,不好的例子。但是,是的,这是真的。
    • 是的,如果我使用my_model = MyModel.find_by(id: some_id),我几乎从不使用my_model.present?,所以我同意你的看法。请注意,#present? 对于空数组、空哈希甚至 ActiveRecord::Relation 也很有用(hoiwever),如 User.where(last_name: 'Moussolini').present?
    • 谢谢,感谢您的回复。
    【解决方案3】:

    如果您使用字符串,则仅检查属性或对象是否存在将返回 true,但 present 方法将返回 false。

    这里有一些例子:

    # Double negation return the boolean value
    !!""
    => true
    
    
    "".present?
    => false
    
    " ".present?
    => false
    
    [].present?
    => false
    
    nil.present?
    => false
    
    true.present?
    => true
    
    false.present?
    => false
    
    {}.present?
    => false
    
    person = {:firstName => "John", :lastName => "Doe"}
    person.present?
    => true
    
    5.present?
    => true
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-20
      • 1970-01-01
      • 2020-05-09
      • 2023-03-02
      • 2013-05-15
      • 1970-01-01
      • 2012-03-26
      • 2021-04-10
      相关资源
      最近更新 更多