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
module API
module V1
class ProjectsController < API::V1::ApplicationController
# GET /projects
def index
render jsonapi: Project.all,
class: { Project: API::V1::SerializableProject },
include: params[:include]
end
In my Serializer I have
module API
module V1
class SerializableProject < JSONAPI::Serializable::Resource
type 'projects'
attributes :name, :job_number
has_many :companies
end
end
end
When I pass the include params with GET /projects?include=companies, I get undefined method 'new' for nil:NilClass. I'm assuming because it can't find API::V1::SerializableCompany
How am I supposed to specify the class for all includes? This was a simplified example, but some of my Models have multiple relationships.
That keeps the render method clean, specially if you many nested objects -- in which case you could end up with a big hash. This apprach is similar to AMS.
@kapso@siepet If you look at the code history, it used to be that way. The reasons it was modified:
It introduces possible inconsistencies (say you're requesting a post and their comments, and the authors of those – a same author could be serialized by two possibly different serializers).
It makes debugging harder because it is not clear what serializer was used and how it was chosen.
Note that in most use-cases, you would use the controller-level hooks to provide a static or dynamic hash, i.e.
And as mentioned, if you have a consistent way of deriving the serializer name from the class name (which you should probably have), you can use a dynamic hash to lazily generate the mapping.
It introduces possible inconsistencies (say you're requesting a post and their comments, and the authors of those – a same author could be serialized by two possibly different serializers)
My code relied exactly on what you called "inconsistencies" to produce tweaks in the serialization that best fit my needs
I have an appointment booking website where users can only access the phone number of people they have an appointments with. Assume I am rendering a user with his contacts, and I want to unlock the phone number for the users they are in contact with through appointments
class User
has_many :conversations
has_many :appointments, through: :conversations
has_and_belongs_to_many :contacts, class_name: :User
field :phone
end
class Conversation
belongs_to :initiator, class_name: User
belongs_to :recipient, class_name: User
has_one :appointment
end
class Appointment
belongs_to :conversation
end
I was taking advantage of a specific "serializer routing" user.appointments.conversation.recipient VS user.contacts to show the phone number
The phone number would be serialized for those users that have an appointment with the user, since I would declare a different serializer in the ConversationSerializer
class AppointmentSerializer
belongs_to :conversation, class: Appointment::ConversationSerializer
end
class Appointment::ConversationSerializer
belongs_to :recipient, class:: Appointment::Conversation::UserWithPhoneSerializer
belongs_to :initiator, class:: Appointment::Conversation::UserWithPhoneSerializer
end
class Appointment::Conversation::UserWithPhoneSerializer
attribute :phone
end
# VS
class UserSerializer
# no phone attribute
has_many :contacts, class_name: 'UserSerializer'
end
Now I agree this is a bit of a (dirty hack), since we have no way of deciding which serializer to actually use (not sure where this is a first hit first serialize or something else), but it did serve me perfectly on this one. Not sure how to reproduce something similar on the new jsonapi-rb 0.3+. Or maybe something using decorators ? sounds like painful...
But if you have an idea / suggestion and it works, I'd migrate right away to jsonapi-rails 3.x
This is basically what prevent me from upgrading to jsonapi_compliable 0.11 of @richmolj that upgraded jsonapi-rails 0.2.x to 0.3.x
It makes debugging harder because it is not clear what serializer was used and how it was chosen.
class ApplicationSerializer < JSONAPI::Serializable::Resource
if Rails.env.development?
# @override in dev environment to inject serializer name
def as_jsonapi(*)
super.tap do |hash|
(hash[:meta] ||= {}).merge!(serializer_name: self.class.name)
end
end
end
end
killed it once and for all (maybe not for the "how it was chosen" part, but this is mainly the library user's job I would say)
Activity
[-]Specify class for include relatoinship[/-][+]Specify class for include relationship[/+][-]Specify class for include relationship[/-][+]Specify class when including relationships[/+]beauby commentedon Dec 12, 2017
Hi @KidA001 – the
classrender option takes a hash that maps your models to your serializers. In your case, you should do:If your serializers have a consistent naming scheme, you could override the
jsonapi_classhook as follows:kapso commentedon Apr 20, 2018
I think a cleaner approach would be to specify the class name inside serializer, so something like
belongs_to :customer, class: Api::V1::SerializableCustomerThat keeps the
rendermethod clean, specially if you many nested objects -- in which case you could end up with a big hash. This apprach is similar to AMS.@beauby thoughts?
siepet commentedon Jul 31, 2018
I agree with @kapso, going with default serializer class for relationship by doing
would be a nice thing to add.
beauby commentedon Jul 31, 2018
@kapso @siepet If you look at the code history, it used to be that way. The reasons it was modified:
Note that in most use-cases, you would use the controller-level hooks to provide a static or dynamic hash, i.e.
beauby commentedon Jul 31, 2018
And as mentioned, if you have a consistent way of deriving the serializer name from the class name (which you should probably have), you can use a dynamic hash to lazily generate the mapping.
kapso commentedon Jul 31, 2018
@beauby yea I ended up using a controller method as well in my
BaseControllerStartouf commentedon Sep 12, 2018
@beauby
My code relied exactly on what you called "inconsistencies" to produce tweaks in the serialization that best fit my needs
I have an appointment booking website where users can only access the phone number of people they have an appointments with. Assume I am rendering a user with his contacts, and I want to unlock the phone number for the users they are in contact with through appointments
I was taking advantage of a specific "serializer routing"
user.appointments.conversation.recipientVSuser.contactsto show the phone numberThe phone number would be serialized for those users that have an appointment with the user, since I would declare a different serializer in the ConversationSerializer
Now I agree this is a bit of a (dirty hack), since we have no way of deciding which serializer to actually use (not sure where this is a first hit first serialize or something else), but it did serve me perfectly on this one. Not sure how to reproduce something similar on the new jsonapi-rb 0.3+. Or maybe something using decorators ? sounds like painful...
But if you have an idea / suggestion and it works, I'd migrate right away to jsonapi-rails 3.x
This is basically what prevent me from upgrading to jsonapi_compliable 0.11 of @richmolj that upgraded jsonapi-rails 0.2.x to 0.3.x
killed it once and for all (maybe not for the "how it was chosen" part, but this is mainly the library user's job I would say)