value_to_boolean已被弃用,有什么好的替代方法吗?

29

在Rails 3.2中,是否有一个“酷孩子认可”的替代方法来替换ActiveRecord::ConnectionAdapters::Column.value_to_boolean


1
你能提供一个使用案例或更多细节吗?你总是可以使用 !! 将任何值转换为布尔值。例如, !!nil 会变成假,而 !!1 会变成真。 - jokklan
1
[false, 0, '0', 'f', 'F', 'false', 'FALSE'].map { |v| !!v } 返回 [false, true, true, true, true, true, true] 时,显然这并不是一种替代方法。 - Gunchars
4个回答

109

在Rails 4.2中,以下可能是一种实现方式:

 ActiveRecord::Type::Boolean.new.type_cast_from_database(value)

它在幕后会执行这个操作

if value == ''
  nil
else
  ConnectionAdapters::Column::TRUE_VALUES.include?(value)
end

或者在 Rails 5 中:

 ActiveRecord::Type::Boolean.new.cast(value)

似乎最终停留在这里:

  def cast_value(value)
    if value == ''
      nil
    else
      !FALSE_VALUES.include?(value)
    end
  end

3
似乎ActiveRecord::Type::Boolean.new.type_cast_from_user(value)会是一个更合适命名的替代方案(具有相同的功能) https://github.com/rails/rails/blob/v4.2.3/activerecord/lib/active_record/type/value.rb#L33 - Manuel Meurer
7
针对Rails 5,今天我不得不使用ActiveRecord::Type::Boolean.new.cast而不是type_cast。 - Thibaut Barrère
谢谢,我会更新。我有一段时间没有使用Rails 5了。 - John Naegle
ActiveRecord::Type::Boolean.new.cast(value) - Jake
有一个小问题:value_to_boolean 用于将 nil 转换为 false,而 type_cast_from_database 不会这样做(在这种情况下它会返回 nil)。如果您有非空约束,则可能会导致错误。 - fabi
注意,如果您转换符号,请小心,因为 :'' 被转换为 true(我正在将可以为 nil 的布尔列转换为本地化字符串)。 - Goulven

12
如评论中所提到的,答案取决于您想要做什么?您想接受所有类型的字符串并将它们转换为真正的布尔值吗?还是您也控制了提交端,可以更加严格?
从严格到更加神奇:
双重否定法可以将任何对象转换为真正的布尔值。第一个否定将其变成相反的形式,第二个则将其变为正确的布尔值。
基本上,nilfalse将变为false,其他所有内容都将变为true
!!nil     # => false
!!false   # => false
!!0       # => true
!!true    # => true
!!""      # => true
!!"false" # => true
!![]      # => true

适用于导出为 JSON,但在 Ruby 中保留时并不是真正需要的。

Object#present?

来自 ActiveSupport,与 blank? 相反:

nil.present?     # => false
false.present?   # => false
0.present?       # => true
"false".present? # => true
"".present?      # => false
[].present?      # => false

Array#include?

指定特定的字符串,使其为假或真:

not [nil, false, 0, '0', 'f', 'F', 'false', 'FALSE'].include?(value.presence)

或者反过来说:
[true, 1, '1', 't', 'T', 'true', 'TRUE'].include?(value)

如果您正在处理带有复选框的表单提交,或者处理外部输入并希望更加宽容,则这些非常方便。当然,您可以自己决定要接受什么。


感谢您提供的所有信息。看起来 !! 是我正在寻找的语法糖... - Chris B
4
如果你想让字符串"false"在使用!!时返回布尔值false,那么就像 iain 的回答一样,这并不明显。使用 !!"false" 会返回true,你将不得不找到一个麻烦的 bug。如果你在 Rails 中只是想检查是否存在,那么最好使用 Active Support Core Extensions 中更明确的#present?#blank? 方法。 - Chad M

1

ActiveRecord::Type::Boolean.new.type_cast_from_database(value)如果值为nil/空(''),则返回nil。

ActiveRecord::Type::Boolean.new.type_cast_from_database(nil) # => nil ActiveRecord::Type::Boolean.new.type_cast_from_database('') # => nil

我更喜欢使用!!ActiveRecord::Type::Boolean.new.type_cast_from_database(value)将输入值转换为布尔值

!!ActiveRecord::Type::Boolean.new.type_cast_from_database(nil) # => false !!ActiveRecord::Type::Boolean.new.type_cast_from_database('') # => false


感谢您的质量保证! - Stuart Hannig

0

1
我认为它并没有被弃用,但他们在类中添加了stopdoc,我认为这意味着它仅供内部使用。 - moger777
9
它在Rails 4.2中被移除了。 - John Naegle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接