【问题标题】:Is there built in support in rails for the default value substitution idiom?Rails 中是否有对默认值替换习惯用法的内置支持?
【发布时间】:2011-04-07 14:26:54
【问题描述】:

我经常编写代码来在遇到 nil/empty 值时提供默认值。

例如:

category = order.category || "Any"
#  OR
category = order.category.empty? ? "Any" : order.category

我即将扩展try 方法来处理这个习语。

category = order.try(:category, :on_nill => "Any")
#  OR
category = order.try(:category, :on_empty=> "Any")

我想知道 Rails/Ruby 是否有一些方法来处理这个习语?

注意:

我正在尝试消除基于 || / or / ? 运算符的成语的重复。

本质上,我正在寻找与try 等效的方法来处理默认替换方案。

没有try方法:

product_id = user.orders.first.product_id unless user.orders.first.nil? 

try方法:

product_id = user.orders.first.try(:product_id)

很容易实现一个通用的方法来处理这个习语,但我想确保我不会重新发明轮子。

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    this question。 ActiveSupport 向所有对象添加一个presence 方法,如果present?(与blank? 相反)则返回其接收者,否则为nil

    例子:

    host = config[:host].presence || 'localhost'
    

    【讨论】:

      【解决方案2】:

      也许这可能有用:

      class Object
        def subst_if(condition, replacement)
          condition = send(condition) if condition.respond_to?(:to_sym)
          if condition
            replacement
          else  
            self
          end
        end
      end
      

      这样使用:

      p ''.subst_if(:empty?, 'empty')       # => "empty"
      p 'foo'.subst_if(:empty?, 'empty')    # => "foo"
      

      它也需要独立条件,与对象无关:

      p 'foo'.subst_if(false, 'bar')    # => 'foo'
      p 'bar'.subst_if(true,  'bar')    # => 'bar'
      

      我对@9​​87654324@ 这个名字并不感兴趣。如果我知道的话,我会借用 Lisp 为这个函数使用的任何名称(假设它存在)。

      【讨论】:

      • +1,这是一个有趣的方法。我正在考虑扩展 try 方法,因为我已经在很多地方使用它。
      【解决方案3】:

      很确定它没有被烘烤。这是指向similar question/answer 的链接。这是我采取的方法。利用 ruby​​:||= 语法

      旁白:这个问题也让我想起了有史以来的第一个 Railscast:Caching with instance variables 如果你需要在 Controller 中执行这种操作,这是一个有用的截屏视频

      【讨论】:

        【解决方案4】:

        fetch 将在您通过数组的index 值或散列中的keys (或ActionController::Parameters 又名params)查找值的情况下工作。否则,您将不得不使用其他答案中所述的||=attempted_value || default_value

        这里重写了当前接受的答案示例:

        假设:config = { my_host_ip: '0.0.0.0' }

         config.fetch(:my_host_ip, 'localhost')
         # => "0.0.0.0" 
        
         config.fetch(:host, 'localhost')
         # => "localhost"
        

         a_thru_j = ('a'..'j').to_a
         # => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
        
         a_thru_j.fetch(1, 'not here')
         # => "b"
        
         a_thru_j.fetch(10, 'not here')
         # => "not here"
         
        

        注意:如果没有默认值,当key/index 不存在时会引发错误:

         config.fetch(:host)
         # => KeyError: key not found: :host
        
         params.fetch(:host)
         # => ActionController::ParameterMissing: param is missing or the value is empty: host
        
         a_thru_j.fetch(10)
         # => index 10 outside of array bounds: -10...10
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-11-03
          • 2011-07-22
          • 2017-07-28
          • 2013-01-17
          • 2012-04-10
          • 2012-12-01
          相关资源
          最近更新 更多