Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there any way to pass arguments to a relationship resource? #110

Open
connor-odoherty opened this issue Jul 18, 2019 · 1 comment
Open

Comments

@connor-odoherty
Copy link

connor-odoherty commented Jul 18, 2019

Let's say we have a model Professor.rb that is serialized by the SerializableProfessor. The professor has the attributes:

  • name
  • age
  • phone_number

In certain cases, depending on the class (or even higher up the chain, depending on the Student who has_many Lectures, which has_one Professor), I want to be able to return the phone_number as itself, or as nil.

In this contrived example, the Professor model does not know anything about Lectures. A Lecture has_one Professor, but the Professor DOES NOT have_many Lectures.

Is there any way to tell SerializableProfessor whether or not to show the phone_number from SerializableLecture?

Ideally, SerializableLecture would look like so:

class SerializableLecture < ApplicationSerializer
  ...
  ...
  has_one :professor do
    data do
      @object.professor
    end
    arguments do
      { show_phone_number: false }
    end
  end
end

and SerializableProfessor could do:

class SerializableProfessor < ApplicationSerializer
    extend JSONAPI::Serializable::Resource::ConditionalFields

   attribute :phone_number, unless -> { @arguments[:phone_number] }
end

OR

Even better, we could conditionally decide which Serializer to use. Maybe we have a base SerializableProfessor, and we have SerializableProfessorWithContactInfo and SerializableProfessorWithoutContactInfo. Then, we do something like:

class SerializableLecture < ApplicationSerializer
  ...
  ...
  has_one :professor do
    data do
      @object.professor
    end
    serializer_to_use do
      @object.is_a_lecture_with_contact_info? ? SerializableProfessorWithContactInfo : SerializableProfessorWithoutContactInfo
    end
  end
end

While I could use expose define a mapping of Professor UUIDs to whether or not I should be returning contact info, this could become performance costly at a large scale, non-contrived scenario.

Beyond what I have proposed, are there any other ways to achieve that desired behavior?

Additionally, if I can't do anything from the relationship perspective, is there any way to access the serialization capabilities of a single Serializable resource class? That way, instead of defining a has_one, I could do:

class SerializableLecture < ApplicationSerializer
  ...
  ...
  attribute :professor do
    serialized_professor = SerializableProfessor.new(@object.professor)
    serialized_professor[:phone_number] = @object.is_a_lecture_with_contact_info? ? @object.professor.phone_number : nil
    serialized_professor
  end
end

I understand that the issue here is: 'What happens if Professor A when referenced from Lecture A is supposed to show phone_number, but when referenced from Lecture B, they are not supposed to return phone_number?'. Maybe we can keep track of all arguments passed on a resource to resource level, and then allow the resource itself to determine what to do with those collected arguments?

@allencch
Copy link

allencch commented Dec 1, 2022

I have similar situation. But I solve it by create another serializable class with inheritance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants