Skip to content

Commit

Permalink
fix: Enum should allow the conventionally case-sensitive operators (g…
Browse files Browse the repository at this point in the history
…raphiti-api#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>
  • Loading branch information
jasonkarns and jkeen committed Mar 27, 2024
1 parent 3933323 commit 7afa557
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/graphiti/adapters/abstract.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def self.default_operators
:not_match
],
uuid: [:eq, :not_eq],
enum: [:eq, :not_eq],
enum: [:eq, :not_eq, :eql, :not_eql],
integer_id: numerical_operators,
integer: numerical_operators,
big_decimal: numerical_operators,
Expand Down
2 changes: 2 additions & 0 deletions lib/graphiti/adapters/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def filter_eq(scope, attribute, value)
alias_method :filter_boolean_eq, :filter_eq
alias_method :filter_uuid_eq, :filter_eq
alias_method :filter_enum_eq, :filter_eq
alias_method :filter_enum_eql, :filter_eq

def filter_not_eq(scope, attribute, value)
scope.where.not(attribute => value)
Expand All @@ -37,6 +38,7 @@ def filter_not_eq(scope, attribute, value)
alias_method :filter_boolean_not_eq, :filter_not_eq
alias_method :filter_uuid_not_eq, :filter_not_eq
alias_method :filter_enum_not_eq, :filter_not_eq
alias_method :filter_enum_not_eql, :filter_not_eq

def filter_string_eq(scope, attribute, value, is_not: false)
column = column_for(scope, attribute)
Expand Down
27 changes: 27 additions & 0 deletions spec/filtering_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,33 @@ def self.name
end
end

context "when filtering on an string_enum field" do
before do
resource.config[:filters] = {}
resource.filter :first_name, :string_enum, single: true, allow: ["William", "Harold"] do
eq do |scope, value|
scope[:conditions][:first_name] = value
scope
end
end
end

it "accepts values in the allowlist with eq operator" do
params[:filter] = {first_name: {eq: "William"}}
expect(records.map(&:id)).to eq([employee3.id])
end

it "accepts values in the allowlist with eql operator" do
params[:filter] = {first_name: {eql: "Harold"}}
expect(records.map(&:id)).to eq([employee4.id])
end

it "accepts values in the allowlist with not_eql operator" do
params[:filter] = {first_name: {not_eql: "Harold"}}
expect(records.map(&:id)).to eq([employee1.id, employee2.id, employee3.id])
end
end

context "when only allowing single values" do
before do
resource.filter :first_name, :string, single: true do
Expand Down
13 changes: 13 additions & 0 deletions spec/fixtures/poro.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ def apply_filtering(records, params)
end
if value.is_a?(Array)
value.include?(db_value)
elsif value.is_a?(Hash) && value[:not]
db_value != value[:not]
else
db_value == value
end
Expand Down Expand Up @@ -305,6 +307,13 @@ def filter(scope, name, value)
scope[:conditions][name] = value
scope
end

def filter_not_eq(scope, name, value)
scope[:conditions] ||= {}
scope[:conditions][name] = {not: value}
scope
end

alias_method :filter_integer_eq, :filter
alias_method :filter_string_eq, :filter
alias_method :filter_big_decimal_eq, :filter
Expand All @@ -314,6 +323,10 @@ def filter(scope, name, value)
alias_method :filter_boolean_eq, :filter
alias_method :filter_hash_eq, :filter
alias_method :filter_array_eq, :filter
alias_method :filter_enum_eq, :filter
alias_method :filter_enum_not_eq, :filter_not_eq
alias_method :filter_enum_eql, :filter
alias_method :filter_enum_not_eql, :filter_not_eq

# No need for actual logic to fire
def count(scope, attr)
Expand Down

0 comments on commit 7afa557

Please # to comment.