>> current_user.first_visit
=> 0
>> if current_user.first_visit
>> puts "test"
>> end
test
=> nil
Почему он печатает тест?
>> current_user.first_visit
=> 0
>> if current_user.first_visit
>> puts "test"
>> end
test
=> nil
Почему он печатает тест?
В Ruby только nil можно считать аналогом false. Нет предположения, что 0, "" или [] означает false, поэтому вы должны использовать == 0, .blank?, .empty?, .zero? и т.д.
Но nil не всегда ведет себя как false. Например, при строчной интерполяции метод .to_s применяется к содержимому #{}, который работает по-разному для FalseClass и NilClass:
irb(main)> "qwe #{false} rty"
=> "qwe false rty"
irb(main)> "qwe #{nil} rty"
=> "qwe rty"
Вы можете думать о Ruby, если в качестве тестирования логического или для доступности данных (vs nil). Неявное преобразование от 0 к ложному, поддерживаемое C и (следовательно, другие языки, такие как С++), было более историческим артефактом за несколько дней до того, как C имел отчетливый булевский тип. Там он полагается на то, что 0 является удобной дозорной величиной или имеет интуитивное значение. Для многих вещей (например, в какой-то стране, где размеры одежды варьируются от 0 до 8, результаты вызова функции POSIX libC), ноль не преобразуется красиво в логически эквивалентное булево, поэтому не так уж плохо, что Ruby идет своим путем.
С этой точки зрения проблема с вашим кодом заключается в том, что current_user.first_visit - имя которого подразумевает логический тип - фактически содержит 0, а не false. В качестве альтернативы, если у вас есть явно числовой current_user.visit_counter, было бы естественно и правильно использовать один из:
current_user.visit_counter > 0
current_user.visit_counter >= 1
current_user.visit_counter != 0
Вы можете попробовать это
>> current_user.first_visit
=> 0
>> if current_user.first_visit != 0
>> puts "test"
>> else
>> puts "fail"
>> end
fail
=>nil
При проверке числовых значений вам также необходимо сопоставить его с ожидаемым значением