Skip to content

Commit 56d34fd

Browse files
jasonkarnsjkeen
andauthored
fix: Enum should allow the conventionally case-sensitive operators (#434)
Add eql and not_eql operators to enum for case-sensitive matching, aligning with string behavior and improving polymorphic association ergonomics --------- Co-authored-by: Jeff Keen <jeff@keen.me>
1 parent 0b2d9ff commit 56d34fd

4 files changed

Lines changed: 43 additions & 1 deletion

File tree

lib/graphiti/adapters/abstract.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def self.default_operators
3939
:not_match
4040
],
4141
uuid: [:eq, :not_eq],
42-
enum: [:eq, :not_eq],
42+
enum: [:eq, :not_eq, :eql, :not_eql],
4343
integer_id: numerical_operators,
4444
integer: numerical_operators,
4545
big_decimal: numerical_operators,

lib/graphiti/adapters/active_record.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def filter_eq(scope, attribute, value)
2626
alias_method :filter_boolean_eq, :filter_eq
2727
alias_method :filter_uuid_eq, :filter_eq
2828
alias_method :filter_enum_eq, :filter_eq
29+
alias_method :filter_enum_eql, :filter_eq
2930

3031
def filter_not_eq(scope, attribute, value)
3132
scope.where.not(attribute => value)
@@ -37,6 +38,7 @@ def filter_not_eq(scope, attribute, value)
3738
alias_method :filter_boolean_not_eq, :filter_not_eq
3839
alias_method :filter_uuid_not_eq, :filter_not_eq
3940
alias_method :filter_enum_not_eq, :filter_not_eq
41+
alias_method :filter_enum_not_eql, :filter_not_eq
4042

4143
def filter_string_eq(scope, attribute, value, is_not: false)
4244
column = column_for(scope, attribute)

spec/filtering_spec.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,33 @@ def self.name
580580
end
581581
end
582582

583+
context "when filtering on an string_enum field" do
584+
before do
585+
resource.config[:filters] = {}
586+
resource.filter :first_name, :string_enum, single: true, allow: ["William", "Harold"] do
587+
eq do |scope, value|
588+
scope[:conditions][:first_name] = value
589+
scope
590+
end
591+
end
592+
end
593+
594+
it "accepts values in the allowlist with eq operator" do
595+
params[:filter] = {first_name: {eq: "William"}}
596+
expect(records.map(&:id)).to eq([employee3.id])
597+
end
598+
599+
it "accepts values in the allowlist with eql operator" do
600+
params[:filter] = {first_name: {eql: "Harold"}}
601+
expect(records.map(&:id)).to eq([employee4.id])
602+
end
603+
604+
it "accepts values in the allowlist with not_eql operator" do
605+
params[:filter] = {first_name: {not_eql: "Harold"}}
606+
expect(records.map(&:id)).to eq([employee1.id, employee2.id, employee3.id])
607+
end
608+
end
609+
583610
context "when only allowing single values" do
584611
before do
585612
resource.filter :first_name, :string, single: true do

spec/fixtures/poro.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ def apply_filtering(records, params)
7474
end
7575
if value.is_a?(Array)
7676
value.include?(db_value)
77+
elsif value.is_a?(Hash) && value[:not]
78+
db_value != value[:not]
7779
else
7880
db_value == value
7981
end
@@ -305,6 +307,13 @@ def filter(scope, name, value)
305307
scope[:conditions][name] = value
306308
scope
307309
end
310+
311+
def filter_not_eq(scope, name, value)
312+
scope[:conditions] ||= {}
313+
scope[:conditions][name] = {not: value}
314+
scope
315+
end
316+
308317
alias_method :filter_integer_eq, :filter
309318
alias_method :filter_string_eq, :filter
310319
alias_method :filter_big_decimal_eq, :filter
@@ -314,6 +323,10 @@ def filter(scope, name, value)
314323
alias_method :filter_boolean_eq, :filter
315324
alias_method :filter_hash_eq, :filter
316325
alias_method :filter_array_eq, :filter
326+
alias_method :filter_enum_eq, :filter
327+
alias_method :filter_enum_not_eq, :filter_not_eq
328+
alias_method :filter_enum_eql, :filter
329+
alias_method :filter_enum_not_eql, :filter_not_eq
317330

318331
# No need for actual logic to fire
319332
def count(scope, attr)

0 commit comments

Comments
 (0)