Skip to content

Commit 3475be5

Browse files
committed
Fix #as_query to provide format ready to convert to URL params
- Enhanced `as_query` method to handle dynamic filters correctly, ensuring proper serialization of query arguments. - Added `as_json` method to provide JSON representation of datagrid attributes. - Updated `query_params` to use string keys for consistency. - Extended `TRUTH` array in `Utils` to include "y" for boolean conversion. - Adjusted tests to reflect changes in serialization and parameter handling.
1 parent 0a88afa commit 3475be5

File tree

7 files changed

+71
-12
lines changed

7 files changed

+71
-12
lines changed

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,29 @@
11
# Changelog
22

3+
## [2.0.7]
4+
35
* Raise `Datagrid::ConfigurationError` when column or filter name
46
specified in `before` or `after` option not found.
7+
* Fixed `as_query` method when dynamic filter is used. Fixes [#344](https://github.com/bogdan/datagrid/issues/344)
8+
9+
``` ruby
10+
grid = ProductsGrid.new(category: 'dresses', available: true, condition: ["price", ">=", 25])
11+
# Before
12+
grid.as_query
13+
# => {
14+
# category: 'dresses',
15+
# available: true,
16+
# condition: #<Object>
17+
# }
18+
# After
19+
grid.as_query
20+
# => {
21+
# "category" => 'dresses',
22+
# "available" => true,
23+
# "condition" => { "field" => "price", "operation" => ">=", "value" => "25" }
24+
# }
25+
```
26+
527

628
## [2.0.6]
729

lib/datagrid/core.rb

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
require "datagrid/drivers"
44
require "active_support/core_ext/class/attribute"
5+
require "active_support/core_ext/object/json"
56
require "active_model/attribute_assignment"
67

78
module Datagrid
@@ -210,16 +211,15 @@ def assets
210211
scope
211212
end
212213

213-
# @return [Hash{Symbol => Object}] serializable query arguments skipping all nil values
214+
# @return [Hash{String => Object}] serializable query arguments skipping all nil values
214215
# @example
215216
# grid = ProductsGrid.new(category: 'dresses', available: true)
216217
# grid.as_query # => {category: 'dresses', available: true}
217218
def as_query
218-
attributes = self.attributes.clone
219-
attributes.each do |key, value|
220-
attributes.delete(key) if value.nil?
219+
self.attributes.reduce({}) do |result, (k,v)|
220+
result[k.to_s] = v.as_json unless v.nil?
221+
result
221222
end
222-
attributes
223223
end
224224

225225
# @return [Hash{Symbol => Hash{Symbol => Object}}] query parameters to link this grid from a page
@@ -228,7 +228,18 @@ def as_query
228228
# Rails.application.routes.url_helpers.products_path(grid.query_params)
229229
# # => "/products?products_grid[category]=dresses&products_grid[available]=true"
230230
def query_params(attributes = {})
231-
{ param_name.to_sym => as_query.merge(attributes) }
231+
{ param_name.to_s => as_query.merge(attributes.stringify_keys) }
232+
end
233+
234+
# @return [Hash{String => Object}] JSON representation of datagrid attributes
235+
# @example
236+
# grid = ProductsGrid.new(category: 'dresses', available: true)
237+
# grid.as_json # => {"category" => 'dresses', "available" => true}
238+
def as_json(options = nil)
239+
attributes.reduce({}) do |result, (k,v)|
240+
result[k.to_s] = v.as_json(options)
241+
result
242+
end
232243
end
233244

234245
# @return [void] redefines scope at instance level

lib/datagrid/filters/dynamic_filter.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ def to_h
143143
{ field: field, operation: operation, value: value }
144144
end
145145

146-
def as_query
147-
to_h
146+
def as_json
147+
{ "field" => field, "operation" => operation, "value" => value }
148148
end
149149

150150
protected

lib/datagrid/helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ def datagrid_order_path(grid, column, descending)
436436
query = request&.query_parameters || {}
437437
ActionDispatch::Http::URL.path_for(
438438
path: request&.path || "/",
439-
params: query.merge(grid.query_params(order: column.name, descending: descending)),
439+
params: query.merge(grid.query_params("order" => column.name, "descending" => descending)),
440440
)
441441
end
442442

lib/datagrid/utils.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module Datagrid
44
# @!visibility private
55
module Utils
66
class << self
7-
TRUTH = [true, 1, "1", "true", "yes", "on"].freeze
7+
TRUTH = [true, 1, "1", "true", "yes", "on", "y"].freeze
88

99
def booleanize(value)
1010
value = value.downcase if value.respond_to?(:downcase)

spec/datagrid/core_spec.rb

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ class EqualTest < Datagrid::Base
244244
end
245245
end
246246

247-
describe ".query_param" do
247+
describe "#query_param" do
248248
it "works" do
249249
grid = test_grid(name: "value") do
250250
scope { Entry }
@@ -253,7 +253,22 @@ def param_name
253253
"grid"
254254
end
255255
end
256-
expect(grid.query_params).to eq({ grid: { name: "value" } })
256+
expect(grid.query_params).to eq({ "grid" => { "name" => "value" } })
257+
end
258+
end
259+
260+
describe "#as_json" do
261+
it "works" do
262+
grid = SimpleReport.new(category: "One", confirmed: true, disabled: true, group_id: 1, name: "hello", order: :category)
263+
expect(grid.as_json).to eq(
264+
"category" => "One",
265+
"confirmed" => true,
266+
"descending" => nil,
267+
"disabled" => "YES",
268+
"group_id" => [1],
269+
"name" => "hello",
270+
"order" => "category",
271+
)
257272
end
258273
end
259274
end

spec/datagrid/filters/dynamic_filter_spec.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,15 @@
218218
grid.condition = ["groups.name", "=~", "Hello"]
219219
expect(grid.assets).to_not include(entry)
220220
end
221+
222+
it "serializes value to array when calling as_query" do
223+
grid = test_grid(condition: ["id", "=", 1]) do
224+
scope { Entry }
225+
filter(:condition, :dynamic)
226+
end
227+
228+
expect(grid.as_query).to eq({
229+
"condition" => {"field" => "id", "operation" => "=", "value" => 1}
230+
})
231+
end
221232
end

0 commit comments

Comments
 (0)