Skip to content

Commit

Permalink
Building new records with enum scopes now works as expected
Browse files Browse the repository at this point in the history
Previously, this would give an `ArgumentError`:

   class Issue < ActiveRecord::Base
     enum :status, [:open, :finished]
   end

   Issue.open.build # => ArgumentError: '0' is not a valid status
   Issue.open.create # => ArgumentError: '0' is not a valid status

PR #13542 muted the error, but the issue remains. This commit fixes
the issue by allowing the enum value to be written directly via the
setter:

   Issue.new.status = 0 # This now sets status to :open

Assigning a value directly via the setter like this is not part of the
documented public API, so users should not rely on this behavior.

Closes #13530.
  • Loading branch information
chancancode committed Jan 3, 2014
1 parent 97e7ca4 commit 788bb40
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 12 deletions.
10 changes: 8 additions & 2 deletions activerecord/lib/active_record/enum.rb
Expand Up @@ -72,10 +72,16 @@ def enum(definitions)
_enum_methods_module.module_eval do
# def status=(value) self[:status] = STATUS[value] end
define_method("#{name}=") { |value|
unless enum_values.has_key?(value) || enum_values.has_value?(value) || value.blank?
if enum_values.has_key?(value)|| value.blank?
self[name] = enum_values[value]
elsif enum_values.has_value?(value)
# Assigning a value directly is not a end-user fetaure, hence it's not documented.
# This is used internally to make building objects from the generated scopes work
# as expected, i.e. +Conversation.archived.build.archived?+ should be true.
self[name] = value
else
raise ArgumentError, "'#{value}' is not a valid #{name}"
end
self[name] = enum_values[value]
}

# def status() STATUS.key self[:status] end
Expand Down
13 changes: 7 additions & 6 deletions activerecord/test/cases/enum_test.rb
Expand Up @@ -79,12 +79,13 @@ class EnumTest < ActiveRecord::TestCase
assert_equal 2, Book::STATUS[:published]
end

test "first_or_initialize with enums' scopes" do
class Issue < ActiveRecord::Base
enum status: [:open, :closed]
end
test "building new objects with enum scopes" do
assert Book.written.build.written?
assert Book.read.build.read?
end

assert Issue.open.empty?
assert Issue.open.first_or_initialize
test "creating new objects with enum scopes" do
assert Book.written.create.written?
assert Book.read.create.read?
end
end
4 changes: 0 additions & 4 deletions activerecord/test/schema/schema.rb
Expand Up @@ -327,10 +327,6 @@ def create_table(*args, &block)
t.string :color
end

create_table :issues, force: true do |t|
t.integer :status
end

create_table :items, force: true do |t|
t.column :name, :string
end
Expand Down

0 comments on commit 788bb40

Please sign in to comment.