-
Notifications
You must be signed in to change notification settings - Fork 8
Relationship handlers
jsonapi_parameters tries to assume the type of relationship by the structure data
tree is.
For instance:
{
data: {
type: 'movies',
attributes: {
title: 'The Terminator',
},
relationships: {
director: {
data: {
id: 682, type: 'directors'
}
}
}
}
}
relationships.director.data
is a Hash
, and so JsonApi::Parameters will assume that it is a to-one relationship.
In contrary, for has_many relationship:
{
data: {
type: 'movies',
attributes: {
title: 'The Terminator',
},
relationships: {
genres: {
data: [{
id: 1, type: 'genres'
},
{
id: 2, type: 'genres'
}]
}
}
}
}
relationships.genres.data
is an Array
, so it is assumed to be a to-many relationship.
There are edge cases however. One example would be scissors
. It can be a to-one relationship, and in this case, it will need some special treatment.
If you would like to remove such a relationship, jsonapi_parameters will not allow you to do it - because to-many relationships cannot be nullified (instead, JSON:API urges you to pass an empty array as a call to "empty" the relationship). But scissors is not a to-many relationship, it is 1-1 relationship - what can we do then? We have to define a custom handler that will tell JsonApi::Parameters specifically what to do with this relationship.
In order to do it, you need to first register a handler:
JsonApi::Parameters::Handlers.add_handler(:handle_plural_nil_as_belongs_to_nil, scissors_handler)
then you need to register relationship handler:
JsonApi::Parameters::Handlers.set_resource_handler(:scissors, :handle_plural_nil_as_belongs_to_nil)
and you're set. Now, if you try this:
{
data: {
type: 'users',
id: '666',
attributes: {
first_name: 'John'
},
relationships: {
scissors: { data: nil }
}
}
}
}
JsonApi::Parameters will return this:
user: { first_name: 'John', id: '666', scissors_id: nil }
Obviously this example is just a very trivial one, and will help us only if we ever want to empty the relationship. Usually the handlers you register will need to contain proper logic that checks what kind of value does the relationship yield, and based on that do some action.
Handlers ARE ALWAYS passed three arguments: relationship_key
, relationship_value
and jsonapi_included
which is an Array
that represents the included
tree in the JSON:API input format. It is especially useful in cases when you want nested attributes to be also passed.
Handlers HAVE TO return an Array
of two objects: (string) relationship key, and (object) relationship value.