新手问题 rails 里面的枚举类型

spfzzz · May 30, 2019 · Last by pynix replied at May 30, 2019 · 1495 hits

在 rails 的枚举为什么将 false 转化为 nil??????

当在 model 里面使用 enum 时,其他的时候都比较方便,例如:

enum status: {
  created: 1,
  applied: 2,
  approved: 3,
  published: 8,
  cancel: 10,
}

各种查询,更新 status 字段都非常的方便!!! ##可是当使用布尔类型时...... 😭

class Admin::Operator < ApplicationRecord
  ...
  enum enabled: { enabled: true, disabled: false }
  ...
end
Admin::Operator.last.disabled!
Admin::Operator Update (0.6ms)  UPDATE `admin_operators` SET `enabled` = NULL, `updated_at` = '2019-05-30 13:35:17' WHERE `admin_operators`.`id` = 1
   (0.2ms)  ROLLBACK
Traceback (most recent call last):
        1: from (irb):20
ActiveRecord::NotNullViolation (Mysql2::Error: Column 'enabled' cannot be null: UPDATE `admin_operators` SET `enabled` = NULL, `updated_at` = '2019-05-30 13:35:17' WHERE `admin_operators`.`id` = 1)

rails 把布尔类型的 false 转换成了 nil,就有点懵逼了!!!!寻寻觅觅发现原来你在这里

#activerecord-5.2.2.1/lib/active_record/enum.rb
def cast(value)
        ##这里的问题!!!!!!!!!!!!!!!!!
        return if value.blank?

        if mapping.has_key?(value)
          value.to_s
        elsif mapping.has_value?(value)
          mapping.key(value)
        else
          assert_valid_value(value)
        end
      end

##如果把 return if value.blank?去掉不是更好吗?为什么 rails 会将 false 转化为 nil???????????

module ActiveRecord
  module Enum
    class EnumType
      module EnumCast
        def cast(value)
          return value.to_s if mapping.key?(value)
          return mapping.key(value) if mapping.value?(value)

          assert_valid_value(value)
        end
      end
      prepend EnumCast
    end
  end
end

enum 文档写的是 Declare an enum attribute where the values map to integers in the database, but can be queried by name

如果只有 true 或者 false 的话,字段用 boolean 好了,使用枚举的那个字段,类型一般都是 integer

Reply to liuminhan

不过是有 true 或者 false,查询或者更新的时候还要写 scope 或者 update 例如上面的例子还要写下面的内容才能实现相同的效果:

scope :enabled, -> { where(enabled: true) }
  scope :disabled, -> { where(enabled: false) }

  def enabled!
    update(enabled: true)
  end

  def disabled!
    update(enabled: false)
  end

其实无所谓了,只是想偷个懒😁

大坑。。。

You need to Sign in before reply, if you don't have an account, please Sign up first.