Skip to content

Commit e82f6ba

Browse files
support enum (#1665)
Co-authored-by: Greg Molnar <gregmolnar@users.noreply.github.com>
1 parent 4d76089 commit e82f6ba

File tree

4 files changed

+58
-0
lines changed

4 files changed

+58
-0
lines changed

lib/ransack/nodes/attribute.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ def associated_collection?
3131
def type
3232
if ransacker
3333
ransacker.type
34+
elsif enum?
35+
:enum
3436
else
3537
context.type_for(self)
3638
end
@@ -54,6 +56,14 @@ def inspect
5456
"Attribute <#{name}>"
5557
end
5658

59+
private
60+
61+
def enum?
62+
bound? &&
63+
klass.respond_to?(:defined_enums) &&
64+
klass.defined_enums.key?(attr_name.to_s)
65+
end
66+
5767
end
5868
end
5969
end

lib/ransack/nodes/value.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ def hash
2424

2525
def cast(type)
2626
case type
27+
when :enum
28+
value
2729
when :date
2830
cast_to_date(value)
2931
when :datetime, :timestamp, :time, :timestamptz

spec/ransack/search_spec.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,49 @@ module Ransack
456456
let(:notable_type_field) {
457457
"#{quote_table_name("notes")}.#{quote_column_name("notable_type")}"
458458
}
459+
let(:people_temperament_field) {
460+
"#{quote_table_name("people")}.#{quote_column_name("temperament")}"
461+
}
462+
463+
context 'when evaluating enums' do
464+
before do
465+
Person.first.update_attribute(:temperament, 'choleric')
466+
end
467+
468+
it 'evaluates enum key correctly' do
469+
s = Search.new(Person, temperament_eq: 'choleric')
470+
471+
expect(s.result.to_sql).not_to match(/#{people_temperament_field} = 0/)
472+
expect(s.result.to_sql).to match(/#{people_temperament_field} = #{Person.temperaments[:choleric]}/)
473+
expect(s.result).not_to be_empty
474+
end
475+
476+
it 'evaluates enum value correctly' do
477+
s = Search.new(Person, temperament_eq: Person.temperaments[:choleric])
478+
479+
expect(s.result.to_sql).not_to match(/#{people_temperament_field} = 0/)
480+
expect(s.result.to_sql).to match(/#{people_temperament_field} = #{Person.temperaments[:choleric]}/)
481+
expect(s.result).not_to be_empty
482+
end
483+
end
484+
485+
# Regression test for https://github.com/activerecord-hackery/ransack/issues/1644
486+
context 'when enum fix does not break boolean predicate casting' do
487+
it 'casts 0 to false for not_null predicate' do
488+
s = Search.new(Person, name_not_null: 0)
489+
expect(s.result.to_sql).to match(/#{people_name_field} IS NULL/)
490+
end
491+
492+
it 'casts 1 to true for not_null predicate' do
493+
s = Search.new(Person, name_not_null: 1)
494+
expect(s.result.to_sql).to match(/#{people_name_field} IS NOT NULL/)
495+
end
496+
497+
it 'casts "false" to false for not_null predicate' do
498+
s = Search.new(Person, name_not_null: 'false')
499+
expect(s.result.to_sql).to match(/#{people_name_field} IS NULL/)
500+
end
501+
end
459502

460503
it 'evaluates conditions contextually' do
461504
s = Search.new(Person, children_name_eq: 'Ernie')

spec/support/schema.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class Person < ApplicationRecord
6464
has_many :articles
6565
has_many :story_articles
6666

67+
enum :temperament, { sanguine: 1, choleric: 2, melancholic: 3, phlegmatic: 4 }
68+
6769
has_many :published_articles, ->{ where(published: true) },
6870
class_name: "Article"
6971
has_many :comments
@@ -304,6 +306,7 @@ def self.create
304306
t.boolean :awesome, default: false
305307
t.boolean :terms_and_conditions, default: false
306308
t.boolean :true_or_false, default: true
309+
t.integer :temperament
307310
t.timestamps null: false
308311
end
309312

0 commit comments

Comments
 (0)