【问题标题】:If string is empty then return some default value如果字符串为空,则返回一些默认值
【发布时间】:2011-01-27 14:03:03
【问题描述】:

我经常需要检查某个值是否为空白,然后像这样写下“没有数据存在”:

@user.address.blank? ? "We don't know user's address" : @user.address

当我们有大约 20 到 30 个需要以这种方式处理的字段时,它就变得丑陋了。

我所做的是带有or 方法的扩展String 类

class String
  def or(what)
    self.strip.blank? ? what : self
  end
end

@user.address.or("We don't know user's address")

现在看起来好多了。但它仍然是原始和粗糙的

如何更好地解决我的问题。也许扩展ActiveSupport class 或使用辅助方法或mixins 或其他任何东西会更好。 Ruby 的理念、您的经验和最佳实践可以告诉我什么。

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

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

    例子:

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

    【讨论】:

    • 这很酷。默认的 rails posibility 是首选。谢谢!
    • 首先它是首选,因为在我的解决方案中,我至少应该扩展 String、Fixnum 和 NilClass。在这里我可以使用没有bycles的清晰代码
    【解决方案2】:

    Phrogz 在 PofMagicfingers 的评论中给了我这个想法,但是压倒一切呢?代替?

    class String
      def |(what)
        self.strip.blank? ? what : self
      end
    end
    
    @user.address | "We don't know user's address"
    

    【讨论】:

      【解决方案3】:

      由于您是在 Ruby on Rails 中执行此操作,因此看起来您正在使用模型。 如果您希望在您的应用中任何地方都有一个合理的默认值,您可以(例如)为您的User 模型覆盖address 方法。

      我不太了解 ActiveRecord,无法为此提供好的代码;在续集中它会是这样的:

      class User < Sequel::Model
        def address        
          if (val=self[:address]).empty?
            "We don't know user's address"
          else
            val
          end
        end
      end
      

      ...但是对于上面的示例,这似乎是将视图逻辑混合到模型中,这不是一个好主意。

      【讨论】:

      • 是的,在模型中设置默认值是个坏主意 :) 我的表单会哭泣
      【解决方案4】:

      您的 or 方法可能会产生一些不需要的副作用,因为始终会评估替代(默认)值,即使字符串不为空。

      例如

      @user.address.or User.make_a_long_and_painful_SQL_query_here
      

      即使地址不为空,也会做额外的工作。也许你可以更新一下(抱歉混淆了单行,试图保持简短):

      class String
        def or what = ""
          self.strip.empty? ? block_given? ? yield : what : self
        end
      end
      
      @user.address.or "We don't know user's address"
      @user.address.or { User.make_a_long_and_painful_SQL_query_here }
      

      【讨论】:

      • 好话。知道了。但是为什么所有的代码都会被执行呢?看:a=2 ; a == 2 ? "ok" : @b = 3 ; @b; #=&gt; nil
      • 它将在进行原始调用时执行,而不是使用三元运算符。所有参数都将在方法调用时进行评估。
      【解决方案5】:

      扩展 ActiveRecord 或单个模型可能比 String 更好。

      在您看来,您可能更喜欢更明确的模式,例如

      @user.attr_or_default :address, "We don't know the user's address"
      

      【讨论】:

      • 这是 Active Record 的一部分吗?没有找到任何参考资料。
      【解决方案6】:

      鲁比:

      unless my_str.empty? then my_str else 'default' end
      

      罗尔:

      unless my_str.blank? then my_str else 'default' end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-26
        • 2021-11-30
        • 1970-01-01
        • 2023-03-07
        • 1970-01-01
        • 2011-04-22
        相关资源
        最近更新 更多