You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Introduce Base.query_format for URL encoding values
Follow-up to [#421][]
Problem
---
Not all HTTP APIs support `snake_case` query parameters. Active
Resource's built-in finders (like `.find(:all, params: { … })`,
`.all(params: { … })`, `where(…)`) do not support transforming keys
prior to their encoding.
If an API expects camelCase keys (like `?firstName=Matz` rather than
`?first_name=Matz`), Active Resource's does not provide a method or hook
to override. The already defined `Base.query_string` method used by the
current implementation is `private`. If a consumer were to override it
(despite depending on or overriding `private` methods being
discouraged), they would need to be responsible for transforming the
`Hash` *and* encoding it to a `String`.
Proposal
---
This commit proposed the introduction of the
`ActiveResource::Formats::UrlEncodedFormat`. It's modeled after the
`XmlFormat` and `JsonFormat`, and defines an `encode` method with the
prior behavior (a call to [Hash#to_query][]). Along with the new class,
this commit also introduce a new `.query_format` class attribute (with
getter and setter methods), modeled after the `.format` class attribute.
Consumers can provide their own implementation with or without depending
on the `ActiveResource::Formats::UrlEncodedFormat`. For example, callers
can camelCase keys:
```ruby
module CamelcaseUrlEncodedFormat
extend self, ActiveResource::Formats::UrlEncodedFormat
def encode(params, options = nil)
params = params.deep_transform { |key| key.to_s.camelcase(:lower) }
super
end
end
class Person < ActiveResource::Base
self.site = "https://example.com"
self.query_format = CamelcaseUrlEncodedFormat
end
Person.where(first_name: "Sean")
# => GET https://example.com/people.json?firstName=Sean
```
The URL encoding only applies to query parameters. Prefix options remain
snake_case:
```ruby
class Person < ActiveResource::Base
self.site = "https://example.com"
self.prefix = "/teams/:team_id"
self.query_format = CamelcaseUrlEncodedFormat
end
Person.where(team_id: 1, first_name: "Sean")
# => GET https://example.com/teams/1/people.json?firstName=Sean
```
This commit also includes changes to the `README.md` example code's
query parameters to demonstrate that keys are `snake_case` by default.
[#421]: #421
[Hash#to_query]: https://api.rubyonrails.org/classes/Hash.html#method-i-to_query
0 commit comments