1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Use the database type to deserialize enum

This fixes incorrect assumptions made by e991c7b that we can assume the
DB is already casting the value for us. The enum type needs additional
information to perform casting, and needs a subtype.

I've opted not to call `super` in `cast`, as we have a known set of
types which we accept there, and the subtype likely doesn't accept them
(symbol -> integer doesn't make sense)

Close #23190
This commit is contained in:
Sean Griffin 2016-01-23 08:42:40 -07:00
parent 8de32bb252
commit 67c1719012
4 changed files with 19 additions and 4 deletions

View file

@ -105,9 +105,10 @@ module ActiveRecord
end
class EnumType < Type::Value # :nodoc:
def initialize(name, mapping)
def initialize(name, mapping, subtype)
@name = name
@mapping = mapping
@subtype = subtype
end
def cast(value)
@ -124,7 +125,7 @@ module ActiveRecord
def deserialize(value)
return if value.nil?
mapping.key(value)
mapping.key(subtype.deserialize(value))
end
def serialize(value)
@ -139,7 +140,7 @@ module ActiveRecord
protected
attr_reader :name, :mapping
attr_reader :name, :mapping, :subtype
end
def enum(definitions)
@ -158,7 +159,9 @@ module ActiveRecord
detect_enum_conflict!(name, name)
detect_enum_conflict!(name, "#{name}=")
attribute name, EnumType.new(name, enum_values)
decorate_attribute_type(name, :enum) do |subtype|
EnumType.new(name, enum_values, subtype)
end
_enum_methods_module.module_eval do
pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index

View file

@ -411,4 +411,14 @@ class EnumTest < ActiveRecord::TestCase
assert book.proposed?, "expected fixture to default to proposed status"
assert book.in_english?, "expected fixture to default to english language"
end
test "uses default value from database on initialization" do
book = Book.new
assert book.proposed?
end
test "uses default value from database on initialization when using custom mapping" do
book = Book.new
assert book.hard?
end
end

View file

@ -14,6 +14,7 @@ class Book < ActiveRecord::Base
enum author_visibility: [:visible, :invisible], _prefix: true
enum illustrator_visibility: [:visible, :invisible], _prefix: true
enum font_size: [:small, :medium, :large], _prefix: :with, _suffix: true
enum cover: { hard: 'hard', soft: 'soft' }
def published!
super

View file

@ -104,6 +104,7 @@ ActiveRecord::Schema.define do
t.column :author_visibility, :integer, default: 0
t.column :illustrator_visibility, :integer, default: 0
t.column :font_size, :integer, default: 0
t.column :cover, :string, default: 'hard'
end
create_table :booleans, force: true do |t|