-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Serialize Object/Array when no AMS Serializer is defined #945
Comments
Needs more info. What is obj? Which ref are you on? (paste output of |
active_model_serializers-7b0a85fdda85 code is called as: render json: {error: 'Result is Invalid'}
# throws exception because serializer is nil Stack trace is less than interesting and I don't currently have an example set up to cause the error, but digging through the code: #action_controller/serialization.rb:23
@_serializer ||= ActiveModel::Serializer.serializer_for(resource) # @_serializer is nil when a serializer for the resource is not explicitly defined.
#action_controller/serialization.rb:47
object = serializer.new(resource, @_serializer_opts) # calls new on serializer when it may be nil Is |
perfect. So, the bug is there's no serializer for Hash. solutions: call
`to_json` on your hash, and the resulting string will be your response
body :)
|
I like my adapter: false workaround. -- edited because it came across assholish, when I didn't mean it to be. |
I suppose we could argue this is a bug in AMS in that if it can't find a serializer for non-string object, it should either just pass it through untouched or call to_json on it depending on the context, since that is what the renderer does it non-string, eventually. |
That would be the best, I think. I also noticed that if you pass it a model that you haven't built a serializer for (yet or at all), it fails in the same way. Previous versions of AMS either passed those objects on to a lower renderer or just called to_json on them. Also chokes in the same way with an association without a serializer. |
Yeah, wanna pair on a PR to pass through if adapter is nil or serializer is nil? |
I need to do some more digging. It looks like it should be passing it to super as soon as serializer comes back nil, which means something else is going on. |
I think you have it on the nose, if I understand what you understand. tl;dr def _render_with_renderer_json(resource, options)
if use_adapter? && (serializer = get_serializer(resource))
# adapter ~ Adapter.create(serializer.new(resource))
super(adapter, options)
else
super(resource, options)
end
end
So, it's surprising that |
Yeah, that's what is confusing me. Let cause this error to occur and see what happens. |
So, that's an easy test to write, no? def render_object_without_serializer
render json: {error: 'Result is Invalid'}
end
def test_render_object_without_serializer
get :render_object_without_serializer
assert_equals @response.body, '{ "error": "Result is Invalid" }'
end |
I got it! render json: ['errors'] It's because it's wrapped in an array. The error isn't in the rendering code, but instead is here: def initialize(objects, options = {})
options.merge!(root: nil)
@objects = objects.map do |object|
serializer_class = options.fetch(
:serializer,
ActiveModel::Serializer.serializer_for(object)
)
serializer_class.new(object, options.except(:serializer))
end
@meta = options[:meta]
@meta_key = options[:meta_key]
end So it's the array serializer that needs to know how to handle non-serializer data. |
Easier test to write. Much harder thing to fix because array serializer feeds that straight in to the adapter which doesn't know how to handle a non-serializer object or string. |
I guess it would need a procy serializer that just calls to_json?
|
Hey ppl, just read trough the thread, I'm happy to see that you narrowed that the issue! |
That should fix it @joaomdmoura, or at least indicate how this should be fixed. It's the same issue at the core if it isn't the exact same issue. |
I think this is the same as #772 |
Just to add some info the def self.get_serializer_for(klass)
serializers_cache.fetch_or_store(klass) do
serializer_class_name = "#{klass.name}Serializer"
serializer_class = serializer_class_name.safe_constantize
if serializer_class
serializer_class
elsif klass.superclass
get_serializer_for(klass.superclass)
end
end
end When using |
It was fixed at #962 |
Seems to be working. Had to switch up to using the FlattenJson serializer for some of the parts where I was building up a serializable hash outside of the context of the controller, but that was an unrelated change. |
This issue has been re-introduced in 0.10.5. "render [{}]" is returning error.
|
@phuongnd08 You've commented on an issue from over a year ago without sufficient information to debug. I can't think of a realistic scenario where you'd be using AMS and render an array with a hash in it to json. Please open a new issue. |
I'm receiving an issue, in latest master, where I receive
NoMethodError (undefined method
new' on nil:NilClass.)` when I attempt to serialize something like, ['Result is invalid'].From everything I can tell, it's rolling through the get_serializer_for method, failing to find a serializer for my object, but trying to create an instance of that serializer anyway. It should fall back to a default serializer.
Sorry if this has been addressed, I checked through the issues but didn't see anything that stood out to me. As a workaround, I'm having to specify "render json: obj, adapter: false" when I want to render a json-ready hash rather than a rails model.
The text was updated successfully, but these errors were encountered: