Skip to content

Commit 99f5d9d

Browse files
committed
Option to coerce "null" to Ruby nil
Filters have new options `allow_nil: true` Option can be set at the resource level `Resource.filters_accept_nil_by_default = true` By default this is set to false. #142
1 parent 9550fec commit 99f5d9d

File tree

6 files changed

+61
-1
lines changed

6 files changed

+61
-1
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
Features:
44

5+
- [158](https://github.com/graphiti-api/graphiti/pull/158) Filters options `allow_nil: true`
6+
Option can be set at the resource level `Resource.filters_accept_nil_by_default = true`.
7+
By default this is set to false. (@zeisler)
58
- [157](https://github.com/graphiti-api/graphiti/pull/157) Using attribute option schema: false.
69
This option is default true and is not effected by only and except options. (@zeisler)
710

lib/graphiti/resource/configuration.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ class << self
8080
:attributes_filterable_by_default,
8181
:attributes_schema_by_default,
8282
:relationships_readable_by_default,
83-
:relationships_writable_by_default
83+
:relationships_writable_by_default,
84+
:filters_accept_nil_by_default
8485

8586
class << self
8687
prepend Overrides
@@ -101,6 +102,7 @@ def self.inherited(klass)
101102
default(klass, :attributes_schema_by_default, true)
102103
default(klass, :relationships_readable_by_default, true)
103104
default(klass, :relationships_writable_by_default, true)
105+
default(klass, :filters_accept_nil_by_default, false)
104106

105107
unless klass.config[:attributes][:id]
106108
klass.attribute :id, :integer_id

lib/graphiti/resource/dsl.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def filter(name, *args, &blk)
3232
dependencies: opts[:dependent],
3333
required: required,
3434
operators: operators.to_hash,
35+
allow_nil: opts.fetch(:allow_nil, filters_accept_nil_by_default)
3536
}
3637
elsif (type = args[0])
3738
attribute name, type, only: [:filterable], allow: opts[:allow]

lib/graphiti/scoping/filter.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ def each_filter
5454
unless type[:canonical_name] == :hash || !value.is_a?(String)
5555
value = parse_string_value(filter.values[0], value)
5656
end
57+
value = parse_string_null(filter.values[0], value)
5758
validate_singular(resource, filter, value)
5859
value = coerce_types(filter.values[0], param_name.to_sym, value)
5960
validate_allowlist(resource, filter, value)
@@ -183,5 +184,11 @@ def parse_string_arrays(value)
183184
value = value[0] if value.length == 1
184185
value
185186
end
187+
188+
def parse_string_null(filter, value)
189+
return if value == "null" && filter[:allow_nil]
190+
191+
value
192+
end
186193
end
187194
end

spec/filtering_spec.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,48 @@ def self.name
202202
end
203203
end
204204

205+
context "when passed null and filter marked allow_nil: true" do
206+
context "with string type" do
207+
before do
208+
resource.filter :first_name, allow_nil: true
209+
employee2.update_attributes(first_name: nil)
210+
params[:filter] = { first_name: "null" }
211+
end
212+
213+
it "works" do
214+
expect(records.map(&:id)).to eq([employee2.id])
215+
end
216+
end
217+
218+
context "with integer type" do
219+
before do
220+
resource.attribute :age, :integer
221+
resource.filter :age, allow_nil: true
222+
employee1.update_attributes(age: 20)
223+
employee2.update_attributes(age: nil)
224+
employee3.update_attributes(age: 30)
225+
employee4.update_attributes(age: 40)
226+
params[:filter] = { age: "null" }
227+
end
228+
229+
it "works" do
230+
expect(records.map(&:id)).to eq([employee2.id])
231+
end
232+
end
233+
end
234+
235+
context "when passed null" do
236+
before do
237+
resource.filter :first_name
238+
employee2.update_attributes(first_name: "null")
239+
params[:filter] = {first_name: "null"}
240+
end
241+
242+
it "defaults to a string" do
243+
expect(records.map(&:id)).to eq([employee2.id])
244+
end
245+
end
246+
205247
context "when passed comma, but filter marked single: true" do
206248
before do
207249
resource.filter :first_name, single: true

spec/resource_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
expect(klass.attributes_schema_by_default).to eq(true)
6868
expect(klass.relationships_readable_by_default).to eq(true)
6969
expect(klass.relationships_writable_by_default).to eq(true)
70+
expect(klass.filters_accept_nil_by_default).to eq(false)
7071
end
7172

7273
context "when rails" do
@@ -152,6 +153,7 @@ def self.name
152153
self.attributes_schema_by_default = false
153154
self.relationships_readable_by_default = false
154155
self.relationships_writable_by_default = false
156+
self.filters_accept_nil_by_default = false
155157
end
156158
end
157159

@@ -166,6 +168,7 @@ def self.name
166168
expect(klass.attributes_schema_by_default).to eq(false)
167169
expect(klass.relationships_readable_by_default).to eq(false)
168170
expect(klass.relationships_writable_by_default).to eq(false)
171+
expect(klass.filters_accept_nil_by_default).to eq(false)
169172
end
170173
end
171174

@@ -295,6 +298,7 @@ class TestResourceOverrideSerializer < PORO::ApplicationSerializer
295298
self.attributes_schema_by_default = false
296299
self.relationships_readable_by_default = false
297300
self.relationships_writable_by_default = false
301+
self.filters_accept_nil_by_default = false
298302
end
299303
end
300304

@@ -309,6 +313,7 @@ class TestResourceOverrideSerializer < PORO::ApplicationSerializer
309313
expect(klass2.attributes_schema_by_default).to eq(false)
310314
expect(klass2.relationships_readable_by_default).to eq(false)
311315
expect(klass2.relationships_writable_by_default).to eq(false)
316+
expect(klass2.filters_accept_nil_by_default).to eq(false)
312317
end
313318
end
314319

0 commit comments

Comments
 (0)