diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2019-02-26 12:47:27 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-26 12:47:27 -0800 |
commit | 55a7051a5a2935c0ced79afc5c81ef7db9e0dd73 (patch) | |
tree | c2deb2905a5887641b953474125ecf74395c4c7b /activerecord | |
parent | 3ee0dabb8443c636bf3b51ef051b4b94ee2af460 (diff) | |
download | rails-55a7051a5a2935c0ced79afc5c81ef7db9e0dd73.tar.gz rails-55a7051a5a2935c0ced79afc5c81ef7db9e0dd73.tar.bz2 rails-55a7051a5a2935c0ced79afc5c81ef7db9e0dd73.zip |
Add negative scopes for all enum values (#35381)
Add negative scopes for all enum values
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/CHANGELOG.md | 14 | ||||
-rw-r--r-- | activerecord/lib/active_record/enum.rb | 6 | ||||
-rw-r--r-- | activerecord/test/cases/enum_test.rb | 5 |
3 files changed, 25 insertions, 0 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 4323c57b9e..ce1f1102d5 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,17 @@ +* Add negative scopes for all enum values. + + Example: + + class Post < ActiveRecord::Base + enum status: %i[ drafted active trashed ] + end + + Post.not_drafted # => where.not(status: :drafted) + Post.not_active # => where.not(status: :active) + Post.not_trashed # => where.not(status: :trashed) + + *DHH* + * Fix different `count` calculation when using `size` with manual `select` with DISTINCT. Fixes #35214. diff --git a/activerecord/lib/active_record/enum.rb b/activerecord/lib/active_record/enum.rb index e6dba66a08..8077630aeb 100644 --- a/activerecord/lib/active_record/enum.rb +++ b/activerecord/lib/active_record/enum.rb @@ -31,7 +31,9 @@ module ActiveRecord # as well. With the above example: # # Conversation.active + # Conversation.not_active # Conversation.archived + # Conversation.not_archived # # Of course, you can also query them directly if the scopes don't fit your # needs: @@ -196,9 +198,13 @@ module ActiveRecord define_method("#{value_method_name}!") { update!(attr => value) } # scope :active, -> { where(status: 0) } + # scope :not_active, -> { where.not(status: 0) } if enum_scopes != false klass.send(:detect_enum_conflict!, name, value_method_name, true) klass.scope value_method_name, -> { where(attr => value) } + + klass.send(:detect_enum_conflict!, name, "not_#{value_method_name}", true) + klass.scope "not_#{value_method_name}", -> { where.not(attr => value) } end end end diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb index 8a0f6f6df1..1423efcf95 100644 --- a/activerecord/test/cases/enum_test.rb +++ b/activerecord/test/cases/enum_test.rb @@ -43,6 +43,11 @@ class EnumTest < ActiveRecord::TestCase assert_equal books(:ddd), Book.forgotten.first assert_equal books(:rfr), authors(:david).unpublished_books.first end + + test "find via negative scope" do + assert Book.not_published.exclude?(@book) + assert Book.not_proposed.include?(@book) + end test "find via where with values" do published, written = Book.statuses[:published], Book.statuses[:written] |