If the `id` attribute for a class isn't taken directly from the object when
serializing it, it may be desirible for other classes that serialize a
relationship with that class to overwrite the relationship IDs they serialize.
For example, suppose we have:
```(ruby)
class Repo < Model
attributes :id, :github_id, :name
associations :configs
end
class Config < Model
attributes :id
belongs_to :repo
end
class RepoSerializer < ActiveModel::Serializer
attributes :id, :name
has_many :update_configs
def id
object.github_id
end
end
class ConfigSerializer < ActiveModel::Serializer
attributes :id
belongs_to :repo
end
```
In the above example, serializing a list of `Repo`s will give the `github_id`
for each one, but serializing a `Config` will give the `id` for its parent repo.
Ideally AMS would inspect the `RepoSerializer` when serializing the `Config`,
and realise it can't just output the foreign key. Unfortunately, getting the
serialization class for the child repo currently requires loading the record
(via evaluating `lazy_assocation`), and loses the performance benefit of the
existing `belongs_to?` path. Instead, I've opted to use
`read_attribute_for_serialization` instead of `object.send` to fetch the
serialized foreign key. This allows the serialized relationship ID to be
overwritten using
```(ruby)
class ConfigSerializer < ActiveModel::Serializer
...
def repo_id
object.repo.github_id
end
end
```
Also, fix test where attributes were included when id was ""
```
1) Failure:
ActionController::Serialization::AdapterSelectorTest#test_render_using_adapter_override
[test/action_c$ntroller/adapter_selector_test.rb:53]:
--- expected
+++ actual
@@ -1 +1 @@
-"{\"data\":{\"id\":\"\",\"type\":\"profiles\",\"attributes\":{\"name\":\"Name 1\",\"description\":\"Description 1\"}}}"
+"{\"data\":null}"
```
For JSONAPI, `include_data` currently means, "should we populate the
'data'" key for this relationship. Current options are true/false.
This adds the `:if_sideloaded` option. This means "only
populate the 'data' key when we are sideloading this relationship." This
is because 'data' is often only relevant to sideloading, and causes a
database hit.
Addresses https://github.com/rails-api/active_model_serializers/issues/1555
If you specify include_data false, and do not have any links for this
relationship, we would output something like:
`{ relationships: { comments: {} } }`
This is not valid jsonapi. We will now render
`{ relationships: { comments: { meta: {} } } }`
Instead.
Relevant jsonapi spec: http://jsonapi.org/format/#document-resource-object-relationships
* Make assocations asserts easier to understand
* Refactor Association into Field like everything else
* Make assocation serializer/links/meta lazier
* Push association deeper into relationship
* Simplify association usage in relationships
* Better naming of reflection parent serializer
* Easier to read association method
The `:attributes` adapter is the default one, but it did not support
key transformation. This was very surprising behavior, since the
"Configuration Options" page in the guides didn't mention that this
behavior was not supported by the attributes adapter.
This commit adds key transform support to the attributes adapter, and
adds documentation about the default transform for the attributes
adapter (which is `:unaltered`).
This commit also handles arrays when transforming keys, which was needed
in the case where you're serializing a collection with the Attributes
adapter. With the JSON adapter, it was always guaranteed to pass a hash
to the KeyTransform functions because of the top-level key. Since there
is no top-level key for the Attributes adapter, the return value could
be an array.
- improves improves serialization_context to take options and not depend
on a `request` object.
- adds descriptive error on missing serialization_context.
- Document overriding `CollectionSerializer#paginated?`.