From e0ad9ae27e9b6dc5460d91761ce6fbd7a92b08f0 Mon Sep 17 00:00:00 2001
From: Amr Tamimi <amrnt0@gmail.com>
Date: Fri, 20 Dec 2013 14:12:59 +0200
Subject: Add the ability to nullify the `enum` column

---
 activerecord/CHANGELOG.md              | 22 ++++++++++++++++++++++
 activerecord/lib/active_record/enum.rb |  7 ++++++-
 activerecord/test/cases/enum_test.rb   | 15 +++++++++++++++
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 66bb018be9..4fdeae70d2 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,25 @@
+*   Add the ability to nullify the `enum` column.
+
+     Example:
+
+         class Conversation < ActiveRecord::Base
+           enum gender: [:female, :male]
+         end
+
+         Conversation::GENDER # => { female: 0, male: 1 }
+
+         # conversation.update! gender: 0
+         conversation.female!
+         conversation.female? # => true
+         conversation.gender  # => "female"
+
+         # conversation.update! gender: nil
+         conversation.gender = nil
+         conversation.gender.nil? # => true
+         conversation.gender      # => nil
+
+     *Amr Tamimi*
+
 *   Connection specification now accepts a "url" key. The value of this
     key is expected to contain a database URL. The database URL will be
     expanded into a hash and merged.
diff --git a/activerecord/lib/active_record/enum.rb b/activerecord/lib/active_record/enum.rb
index 2f8439892b..1d484f7c15 100644
--- a/activerecord/lib/active_record/enum.rb
+++ b/activerecord/lib/active_record/enum.rb
@@ -18,6 +18,11 @@ module ActiveRecord
   #   # conversation.update! status: 1
   #   conversation.status = "archived"
   #
+  #   # conversation.update! status: nil
+  #   conversation.status = nil
+  #   conversation.status.nil? # => true
+  #   conversation.status      # => nil
+  #
   # You can set the default value from the database declaration, like:
   #
   #   create_table :conversations do |t|
@@ -62,7 +67,7 @@ module ActiveRecord
         _enum_methods_module.module_eval do
           # def status=(value) self[:status] = STATUS[value] end
           define_method("#{name}=") { |value|
-            unless enum_values.has_key?(value)
+            unless enum_values.has_key?(value) || value.blank?
               raise ArgumentError, "'#{value}' is not a valid #{name}"
             end
             self[name] = enum_values[value]
diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb
index 35e8a98156..017edcb194 100644
--- a/activerecord/test/cases/enum_test.rb
+++ b/activerecord/test/cases/enum_test.rb
@@ -58,6 +58,21 @@ class EnumTest < ActiveRecord::TestCase
     assert_equal "'unknown' is not a valid status", e.message
   end
 
+  test "assign nil value" do
+    @book.status = nil
+    assert @book.status.nil?
+  end
+
+  test "assign empty string value" do
+    @book.status = ''
+    assert @book.status.nil?
+  end
+
+  test "assign long empty string value" do
+    @book.status = '   '
+    assert @book.status.nil?
+  end
+
   test "constant to access the mapping" do
     assert_equal 0, Book::STATUS[:proposed]
     assert_equal 1, Book::STATUS["written"]
-- 
cgit v1.2.3