# \[Rails\] 什麼時候用 `present?` / `blank?` ? ## 前言 (in Ruby) ### truthy / falsy ``` ruby if a_value puts 'a_value 是 truthy' else puts 'a_value 是 falsy' end ``` ``` ruby all_falsy_values_in_ruby = [nil, false] ``` ### #nil? ``` ruby nil.nil? # true false.nil? # false ``` ``` ruby value = a_method_that_reutrn_something_or_nil_but_not_false puts '跟下面等價' if value puts '跟上面等價' unless value.nil? ``` ## Rails ``` ruby require "active_support" require "active_support/core_ext/object/blank" common_blank_things = [ nil, false, [], {}, '', ] # 看原始碼可以得到更詳細資訊 # https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/object/blank.rb # 這些類型其實都有原本的檢查方法 nil.blank? == nil.nil? false.blank? == !false [].blank? == [].empty? {}.blank? == {}.empty? ''.blank? == ''.empty? # 但 ' '.blank? != ' '.empty? ``` ## 所以什麼時候用? ### 1. 檢查字串是否帶有資訊的時候用 ``` ruby a_string = 'qwertyuiop' send_message(a_string) if a_string.present? raise 'no information!' if a_string.blank? ``` ### 2. 檢查一個不確定型態的物件是否帶有資訊 #### 典型例子 Controller Params ``` ruby params[:data].present? ``` 一個 endpoint 只要 client 端能通過驗證 它可以不透過系統的前端應用直接傳送任何內容的 request 到 server 上 所以在這個例子下 `params[:data]` 可能是 `NilClass`, `Hash`, `Array`, `String`, `Number` ... ## 這些時候並不需要 1. Rails model find 只會回傳 record 或 nil ``` ruby record = Model.find(id) if record record.do_something end ``` 2. Rails has_many 只會回傳 array like 不會回傳 nil 3. 明確知道型別的時候 ``` ruby array = [] things.each do |thing| array << thing if thing.good? end puts 'it is empty' if array.empty? puts 'have some' if array.any? ``` ``` ruby hash = {} things.each do |thing| hash[thing.id] = thing if thing.good? end puts 'it is empty' if hash.empty? puts 'have some' if hash.any? ```