fast_jsonapi
fast_jsonapi copied to clipboard
Set the serializer with polymorphic association
Hi, I would like to know if if is possible to force the serializer with polymorphic relation? The problem is I used namespace.
I have a 3 models:
-
Product::Product
-
Receipt::Receipt
-
Receipt::Ingredient
each one has it's own serializer:
-
Product::ProductSerializer
-
Receipt::ReceiptSerializer
-
Receipt::IngredientSerializer
A ``Receipt::Ingredienthave an
itemwhich can be either a
Product::Productor
Receipt::Receipt`.
The code of my model Receipt::Ingredient
:
class Receipt::Ingredient < ApplicationRecord
belongs_to :item, polymorphic: true
end
The code of my serializer Receipt::IngredientSerializer
:
module Receipt
class IngredientSerializer
include FastJsonapi::ObjectSerializer
belongs_to :item, polymorphic: true
end
end
When I try to serialize I have an exception NameError (uninitialized constant Receipt::ProductSerializer)
.
NameError (uninitialized constant Receipt::ProductSerializer)
If that's not a typo then this is your problem. You don't have a Receipt::ProductSerializer
. You have a Product::ProductSerializer. To be honest using namespaces that have the same names a classes is gonna cause you problems and you're probably not correctly abstracting things with names like that.
It's not a typo problem and the fact my class has the same name as my namespace doesn't change anything, I could rename it the problem stay the same.
Yes I've just been looking closer and I see your problem now
Is the type field in the model being saved correctly with the namespace?
What do you mean? The polymorphic relation work without problem with Rails without doing anything else than belongs_to :item, polymorphic: true
and in database I have to correct class with the namespace like Product::Prodcut
.
In that case it's possibly an issue with fast_jsonapi. As a workaround you may be able to do something like ProductSerializer = Product::ProductSerializer
inside the IngredientSerializer
or even define it in the module.
Thanks, that's what I did for now but that's a big hack.
I expect more something like an option serializer
for polymorphic association like we can define the record_type
.
I'm having a similar issue! I'm using ActiveStorage and want to serialize ActiveStorage::Attachment objects with my AttachmentSerializer
which has no prefixed modules.
In my NewsPostSerializer
, has_many works! (It helps that my association name gives away the needed serializer and there are no modules)
has_many :attachments, polymorphic: true, if: Proc.new { |post| post.attachments.attached? }
But in my DlsClass::GroupSerializer
, has_one is a pain. The following will make "type": "one"
because ActiveStorage wraps it in an Attached::One object with delegation.
has_one :orientation_pdf, polymorphic: true, if: Proc.new { |group| group.orientation_pdf.attached? }
I solved this by applying a block and directly returning the attachment
has_one :orientation_pdf, polymorphic: true, if: Proc.new { |group| group.orientation_pdf.attached? } do |group|
group.orientation_pdf.attachment
end
but because the group serializer is in a module DlsClass::GroupSerializer
, it is trying to find a serializer DlsClass::AttachmentSerializer
and even though in the end I tried explicitly stating the serializer option, this thread makes me think your project is ignoring it because it is a polymorphic association.
has_one :orientation_pdf,
serializer: AttachmentSerializer,
polymorphic: true,
if: Proc.new { |group| group.orientation_pdf.attached? } do |group|
group.orientation_pdf.attachment
end
So this module guessing for a polymorphic association is a major problem.
Well, in fact because this association is not polymorphic I was wrong. I fixed everything:
class DlsClass::GroupSerializer
include FastJsonapi::ObjectSerializer
has_one :orientation_pdf,
record_type: :attachment,
serializer: AttachmentSerializer,
if: Proc.new { |group| group.orientation_pdf.attached? } do |group|
group.orientation_pdf.attachment
end
end
I guess if you were on the ActiveStorage::Attachment side and wanted to serialize the polymorphic record
(record_type, record_id, name) then this would be applicable if modules were involved.