【问题标题】:Check if not nil and not empty in Rails shortcut?检查 Rails 快捷方式中是否不为零且不为空?
【发布时间】:2014-04-09 17:41:32
【问题描述】:

我的用户有一个显示页面,并且每个属性应该只在该页面上可见,如果它不是 nil 并且不是空字符串。下面我有我的控制器,不得不为每个变量编写相同的代码行@user.city != nil && @user.city != "" 非常烦人。我不太熟悉创建自己的方法,但我可以以某种方式创建一个快捷方式来执行以下操作:@city = check_attr(@user.city)?或者有没有更好的方法来缩短这个过程?

users_controller.rb

def show 
  @city = @user.city != nil && @user.city != ""
  @state = @user.state != nil && @user.state != ""
  @bio = @user.bio != nil && @user.bio != ""
  @contact = @user.contact != nil && @user.contact != ""
  @twitter = @user.twitter != nil && @user.twitter != ""
  @mail = @user.mail != nil && @user.mail != ""
end

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    有一种方法可以为您做到这一点:

    def show
      @city = @user.city.present?
    end
    

    present? 方法测试 not-nil plus 有内容。空字符串,由空格或制表符组成的字符串,被认为不存在。

    由于这种模式非常普遍,ActiveRecord 中甚至还有一个快捷方式:

    def show
      @city = @user.city?
    end
    

    这大致等价。

    请注意,测试与nil 几乎总是多余的。 Ruby 中只有两个逻辑错误值:nilfalse。除非变量可以是文字 false,否则这就足够了:

    if (variable)
      # ...
    end
    

    这比偶尔出现的if (!variable.nil?)if (variable != nil) 更可取。 Ruby 倾向于使用更简化的表达方式。

    您想要与nil 进行比较的一个原因是,如果您有一个可以是truefalsenil 的三态变量,并且您需要区分最后两种状态。

    【讨论】:

    • 注意,从 Ruby 2.3.0 开始,您可以使用孤独的运算符摆脱许多多余的 nil 检查,例如 if @user && @user.authenticated 可以简单地变成 if @user&.authenticated
    • 另一个你想要if object.present? 而不是if object 的原因是如果你稍后将对象包装在一个装饰器中,结果会改变,除非你使用.present?philihp.com/2018/prefer-if-object-present-over-if-object.html
    【解决方案2】:

    您可以使用 ActiveSupport 附带的.present?

    @city = @user.city.present?
    # etc ...
    

    你甚至可以这样写

    def show
      %w(city state bio contact twitter mail).each do |attr|
        instance_variable_set "@#{attr}", @user[attr].present?
      end
    end
    

    值得注意的是,如果要测试是否为空白,可以使用.blank?(这与.present?相反)

    另外,不要使用foo == nil。请改用foo.nil?

    【讨论】:

    • @Mayank,OP 正在将实例变量设置为 true/false 值。如果receiver 是非空值,reciever.present? 将返回 true。请参阅我链接的文档以获取更多说明。
    • 谢谢我明白了你的意思,但我无法理解 instance_variable_set "@#{attr}", @user[attr].present 的方式?会工作..?
    • @Mayank,instance_variable_set("@foo", "bar")@foo = "bar" 相同。这只是一种设置实例变量的编程方式^^
    • okz 谢谢,现在我明白了......但还有一件事 javascript:atob("bmFreW90b0BnbWFpbC5jb20=");是什么意思?
    • Mayank,在 javascript 控制台中运行它来找出答案!
    猜你喜欢
    • 2010-09-20
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 2019-01-25
    相关资源
    最近更新 更多