在Rails快捷方式中检查是否为空而不是空?

use*_*402 69 ruby ruby-on-rails

我有一个我的用户的显示页面,每个属性应该只在该页面上可见,如果它不是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
Run Code Online (Sandbox Code Playgroud)

tad*_*man 179

有一种方法可以帮到你:

def show
  @city = @user.city.present?
end
Run Code Online (Sandbox Code Playgroud)

present?为不可─方法测试nil加了内容.空字符串,由空格或制表符组成的字符串被认为不存在.

由于这种模式很常见,甚至在ActiveRecord中也有一个快捷方式:

def show
  @city = @user.city?
end
Run Code Online (Sandbox Code Playgroud)

这大致相当.

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

if (variable)
  # ...
end
Run Code Online (Sandbox Code Playgroud)

这比偶尔出现的常用if (!variable.nil?)if (variable != nil)东西更好.Ruby倾向于使用更简化的表达式.

你想要比较的一个原因nil是你是否有一个三态变量true,false或者nil你需要区分最后两个状态.

  • 注意,从Ruby 2.3.0开始,你可以使用孤独的运算符去除许多冗余的nil检查,例如`if @user && @ user.authenticated`就可以简单地成为`if @ user&.authenticated` (8认同)
  • 您想要使用“if object.present?”而不是“if object”的另一个原因是,如果您稍后将对象包装在装饰器中,则结果将会改变,除非您使用“.present?”。https://philihp.com/2018/prefer-if-object-present-over-if-object.html (2认同)

Tha*_*you 11

你可以使用.present吗?它包含在ActiveSupport中.

@city = @user.city.present?
# etc ...
Run Code Online (Sandbox Code Playgroud)

你甚至可以这样写

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

值得注意的是,如果你想测试某些东西是否为空,你可以使用.blank?(这是相反的.present?)

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