I'm seeing a strange behaviour regarding rails 5, active model serializer and the json-api adapter.
Given the following User model with the Rolify gem:
class User < ActiveRecord::Base
#
# Gem Includes
#
rolify
# Include devise modules.
devise :database_authenticatable,
:recoverable, :rememberable, :trackable, :validatable
include DeviseTokenAuth::Concerns::User
#
# Callbacks
#
after_create :assign_default_role
#
# Attributes
#
attr_accessor :remote_image
#
# Validations
#
validates :name, presence: true, length: {in: 1..100}
validates :last_name, presence: true, length: {in: 1..100}
validates :role_ids, presence: true, on: :update
#
# Relations
#
belongs_to :current_scenario, class_name: "Scenario"
#
# Private Instance Methods
#
def assign_default_role
self.add_role(:user) if self.roles.blank?
end
end
and the following controller code:
def show
@user = User.find(params[:id])
authorize @user
render json: @user, include: ['roles'], status: :ok
end
As you can see, I'm including the roles relationship to be rendered as part of the json api response, with json-api adapter format.
FYI, the UserSerializer:
class UserSerializer < ActiveModel::Serializer
#
# Attributes
#
attributes :id, :email, :name, :last_name, :image_url, :image_thumb_url, :created_at, :updated_at, :current_scenario_id, :last_sign_in_at
#
# Relations
#
has_one :current_scenario
has_many :roles
#
# Methods
#
def image_url
object.image_url
end
def image_thumb_url
object.image_url(:thumb)
end
end
When retrieving the json response, I get the following:
{
"data": {
"id":"2",
"type":"users",
"attributes": {
"email":"[email protected]", ...
},
"relationships": {
"current-scenario": {
"data": {
"id":"204",
"type":"scenarios"
}
},
"roles": {
"data": [
{
"id":1,
"name":"user",
"resource-type":null,
"resource-id":null,
"created-at":"2017-01-23T10:27:08.707-03:00",
"updated-at":"2017-01-23T10:27:08.707-03:00"
},
{
"id":2,
"name":"admin",
"resource-type":null,
"resource-id":null,
"created-at":"2017-01-24T09:40:53.020-03:00",
"updated-at":"2017-01-24T09:40:53.020-03:00"
}
]
}
}
}
}
As you can see, the included relationship roles with all its attributes is inside the relationships fragment of the json-api response. Shouldn't the roles data be inside the included fragment, which by the way is missing? Moreover inside the relationship fragment roles should appear only as a reference like: {relationships: {roles: [{id: "1", type: "role"}, {id: "2", type: "role"}]}
am I wrong?
To contrast this, look what happens when also including the current_scenario
relationship:
{
"data": {
"id":"2",
"type":"users",
"attributes": {
"email":"[email protected]",
"name":"Tomás",
"last-name":"Alvarez",
...
},
"relationships": {
"current-scenario": {
"data": {
"id":"204",
"type":"scenarios"
}
},
"roles": {
"data": [
{
"id":1,
"name":"user",
"resource-type":null,
...
}
]
}
},
"included": [
{
"id":"204",
"type":"scenarios",
"attributes": {
"name":"Scenario reload II",
"description":null,
"created-at":"2017-04-18T11:55:35.242-03:00",
"updated-at":"2017-04-18T11:55:35.242-03:00"
},
"relationships": {
"scenario-stocks": {
"data":[]
}
}
}
]
}
}
See how now the included fragment appears with all the information about current_scenario and only the reference to current_scenario is added to the relationships fragment. Is this because roles is a has_many relationship in the active model serializer while current_scenario is a belongs_to ? Am I understanding wrong the json-api adapter specification?
Many thanks!
Ouch. The inconsistency in the JSON-API
response was because i forgot to add a Role model serializer in the backend side (Rails 5). This is the json response now, which is what i was looking for:
{
"data": {
"id": "2",
"type": "users",
"attributes": {
"email": "[email protected]",
"name": "Tomás",
"last-name": "Alvarez",
"image-url": "http://localhost:3001/uploads/user/image/2/05a4dc7.jpg",
"image-thumb-url": "http://localhost:3001/uploads/user/image/2/thumb_05a4dc7.jpg",
"created-at": "2017-01-23T10:39:12.485-03:00",
"updated-at": "2017-04-25T16:32:14.610-03:00",
"current-scenario-id": 204,
"last-sign-in-at": "2017-04-25T16:29:03.559-03:00"
},
"relationships": {
"current-scenario": {
"data": {
"id": "204",
"type": "scenarios"
}
},
"roles": {
"data": [{
"id": "1",
"type": "roles"
}, {
"id": "2",
"type": "roles"
}]
}
}
},
"included": [{
"id": "204",
"type": "scenarios",
"attributes": {
"name": "Scenario reload II",
"description": null,
"created-at": "2017-04-18T11:55:35.242-03:00",
"updated-at": "2017-04-18T11:55:35.242-03:00"
},
"relationships": {
"scenario-stocks": {
"data": []
}
}
}, {
"id": "1",
"type": "roles",
"attributes": {
"name": "user"
}
}, {
"id": "2",
"type": "roles",
"attributes": {
"name": "admin"
}
}]
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With