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
Follow-up to [#420][]
Background
---
The introduction of `ActiveResource::Base.coder` and the
`ActiveResource::Coder` class added support for encoding and decoding
instances of `Base`.
However, collection-focused methods like `Base.where`, `Base.all`, and
`Base.find(:all)` return `ActiveResource::Collection` instances.
Problem
---
While some collection instances are equivalent to `Array` instances,
they are capable of being parsed into `Hash` values that include
additional metadata (for example, pagination URLs, total counts, etc.).
If applications were to dump results, there is a potential loss of that
metadata.
Proposal
---
First, this commit modifies the `ActiveResource::Coder` class to accept
a boolean `:collection` keyword to treat values as
`ActiveResource::Collection` instances.
Next, extend the `ActiveResource::Collection` class to retain the
originally parsed values as a new `#original_parsed` attribute. It also
defines the `#encode` method to rely on the resource class format for
encoding.
Additionally, extend the `ActiveResource::Serialization` module to also
define a `.collection_coder` class attribute to serve as a convenience
method for consumer to pass to `.serialize …, coder: …`:
```ruby
class Person < ActiveResource::Base
# …
end
class Team < ApplicationRecord
serialize :people, coder: Person.collection_coder
end
```
Like the instance-level coders, collection-level coders constructed with
`collection: true` also accept an encoder proc to transform the value
prior to dumping (for JSON/JSONB columns, for example):
```ruby
class Person < ActiveResource::Base
# …
end
class Team < ApplicationRecord
# pass a to_proc-ready method name
serialize :people, coder: ActiveResource::Coder.new(Person, :original_parsed, collection: true)
# pass a block
serialize :people, coder: ActiveResource::Coder.new(Person, collection: true) do |collection|
collection.original_parsed
end
end
```
[#420]: #420
0 commit comments