I use rails (5.0.1) and active_model_serializers (0.10.2). I would like to somehow conditionally serialize the has_many
associations:
class Question < ApplicationRecord
has_many :responses, :inverse_of => :question
end
class Response < ApplicationRecord
belongs_to :question, :inverse_of => :responses
end
class QuestionSerializer < ActiveModel::Serializer
attributes :id, :title, :created_at, :updated_at
has_many :responses
end
class ResponseSerializer < ActiveModel::Serializer
attributes :id, :title
end
I use jsonapi and querying http://localhost:3000/api/questions/1
I get this response:
Response-1:
{
"data": {
"id": "1",
"type": "questions",
"attributes": {
"title": "First",
"created-at": "2017-02-14T09:49:20.148Z",
"updated-at": "2017-02-14T13:55:37.365Z"
},
"relationships": {
"responses": {
"data": [
{
"id": "1",
"type": "responses"
}
]
}
}
}
}
If I remove has_many :responses
from QuestionSerializer
I get this:
Response-2:
{
"data": {
"id": "1",
"type": "questions",
"attributes": {
"title": "First",
"created-at": "2017-02-14T09:49:20.148Z",
"updated-at": "2017-02-14T13:55:37.365Z"
}
}
}
How do I conditionally get either Response-1 or Response-2 at run time? I tried all the recommendations found - neither works with AMS 0.10.2. Currently, the condition works only this way:
class QuestionSerializer < ActiveModel::Serializer
attributes :id, :title, :created_at, :updated_at
has_many :responses if true
end
OR:
class QuestionSerializer < ActiveModel::Serializer
attributes :id, :title, :created_at, :updated_at
has_many :responses if false
end
In these 2 cases I really get either Response-1 or Response-2. But this is hard-coded and I would like to maybe pass a param into the serializer or do some similar thing.
What should I do?
I think you've kind of answered your own question. If you look into the AMS documentation for associations it says that conditionals are supported.
From what I can tell you're just a typo away
class QuestionSerializer < ActiveModel::Serializer
has_many :responses, if: false
end
The attributes
method also supports the if
option, as described here.
What's your active_model_serializers
version?
EDIT:
I have an error in my answer too. I'm using active_model_serializers (0.10.3)
and I'm able to do
class QuestionSerializer < ActiveModel::Serializer
has_many :responses, if: -> { false }
end
The if
option works with either methods, procs or strings. I think you can decide at runtime by providing a method as the conditional.
class QuestionSerializer < ActiveModel::Serializer
attr_writer :should_render_association
has_many :responses, if: -> { should_render_association }
end
# Usage:
serializer = QuestionSerializer.new(question)
serializer.should_render_association = false
serializer.to_json
# => no "responses" key
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