Skip to content

Commit 121e0ad

Browse files
Merge pull request rails#49769 from jonathanhefner/active_record-enum-non-column-backed
Support non-column-backed attributes for `enum`
2 parents d68e439 + 6d00605 commit 121e0ad

File tree

4 files changed

+26
-21
lines changed

4 files changed

+26
-21
lines changed

activerecord/lib/active_record/enum.rb

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,6 @@ def self.extended(base) # :nodoc:
167167
base.class_attribute(:defined_enums, instance_writer: false, default: {})
168168
end
169169

170-
def load_schema! # :nodoc:
171-
defined_enums.each_key do |name|
172-
unless columns_hash.key?(resolve_attribute_name(name))
173-
raise "Unknown enum attribute '#{name}' for #{self.name}"
174-
end
175-
end
176-
end
177-
178170
class EnumType < Type::Value # :nodoc:
179171
delegate :type, to: :subtype
180172

@@ -255,7 +247,13 @@ def _enum(name, values, prefix: nil, suffix: nil, scopes: true, instance_methods
255247

256248
attribute(name, **options)
257249

258-
decorate_attributes([name]) do |name, subtype|
250+
decorate_attributes([name]) do |_name, subtype|
251+
if subtype == ActiveModel::Type.default_value
252+
raise "Undeclared attribute type for enum '#{name}'. Enums must be" \
253+
" backed by a database column or declared with an explicit type" \
254+
" via `attribute`."
255+
end
256+
259257
subtype = subtype.subtype if EnumType === subtype
260258
EnumType.new(name, enum_values, subtype, raise_on_invalid_values: !validate)
261259
end

activerecord/lib/active_record/model_schema.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,8 +605,6 @@ def load_schema!
605605
columns_hash = columns_hash.except(*ignored_columns) unless ignored_columns.empty?
606606
@columns_hash = columns_hash.freeze
607607
alias_attribute :id_value, :id if @columns_hash.key?("id")
608-
609-
super
610608
end
611609

612610
# Guesses the table name, but does not decorate it with prefix and suffix information.

activerecord/test/cases/enum_test.rb

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,18 +1055,24 @@ def self.name
10551055
ActiveRecord::Base.logger = old_logger
10561056
end
10571057

1058-
test "raises for columnless enums" do
1059-
klass = Class.new(ActiveRecord::Base) do
1060-
def self.name
1061-
"Book"
1062-
end
1063-
enum columnless_genre: [:adventure, :comic]
1058+
test "raises for attributes with undeclared type" do
1059+
klass = Class.new(Book) do
1060+
enum typeless_genre: [:adventure, :comic]
10641061
end
10651062

10661063
error = assert_raises(RuntimeError) do
1067-
klass.columns # load schema
1064+
klass.type_for_attribute(:typeless_genre)
10681065
end
1069-
assert_equal "Unknown enum attribute 'columnless_genre' for Book", error.message
1066+
assert_match "Undeclared attribute type for enum 'typeless_genre'", error.message
1067+
end
1068+
1069+
test "supports attributes declared with a explicit type" do
1070+
klass = Class.new(Book) do
1071+
attribute :my_genre, :integer
1072+
enum my_genre: [:adventure, :comic]
1073+
end
1074+
1075+
assert_equal :integer, klass.type_for_attribute(:my_genre).type
10701076
end
10711077

10721078
test "default methods can be disabled by :_instance_methods" do

railties/test/application/test_test.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,11 +335,14 @@ class UserTest < ActiveSupport::TestCase
335335

336336
app_file "app/models/user.rb", <<-RUBY
337337
class User < ApplicationRecord
338-
enum :type, [:admin, :user]
338+
def self.load_schema!
339+
super
340+
raise "SCHEMA LOADED!"
341+
end
339342
end
340343
RUBY
341344

342-
assert_unsuccessful_run "models/user_test.rb", "Unknown enum attribute 'type' for User"
345+
assert_unsuccessful_run "models/user_test.rb", "SCHEMA LOADED!"
343346
end
344347

345348
private

0 commit comments

Comments
 (0)