Skip to content

Serializer trying to look for attribute where it does not exist [0.10.0] #911

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

Closed
Veske opened this issue May 15, 2015 · 3 comments
Closed
Milestone

Comments

@Veske
Copy link

Veske commented May 15, 2015

So I have this media serializer:

class MediumSerializer < ActiveModel::Serializer
    attributes :id,
               :text,
               :image_video_file_name,
               :image_video_croppable_url,
               :image_video_thumb_url,
               :image_video_big_url

    belongs_to :user
    has_many :comments
end

And the has_many :comments looks for this serializer:

class CommentSerializer < ActiveModel::Serializer
    attributes :id,
               :text,
               :user_id,
               :medium_id

    belongs_to :user
end

Now in my controller I am querying for media, so I get an array of mediums.

media = current_user.feed
respond_with media, each_serializer: MediumSerializer

def feed
    user_ids = $redis.smembers(self.redis_relationship_key(:following)) << id
    Medium.includes([{comments: :user}, :user]).where(user_id: user_ids)
end

And now when I load the page that uses this serializer, I get this error:

NoMethodError - undefined method `image_video_file_name' for #<Comment:0x007fa396787828>:
  activemodel (4.2.0) lib/active_model/attribute_methods.rb:433:in `method_missing'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer.rb:37:in `block (2 levels) in attributes'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer.rb:200:in `block in attributes'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer.rb:198:in `each'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer.rb:198:in `each_with_object'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer.rb:198:in `attributes'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer/adapter/json.rb:22:in `block (3 levels) in serializable_hash'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer/adapter.rb:53:in `cache_check'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer/adapter/json.rb:21:in `block (2 levels) in serializable_hash'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer/array_serializer.rb:5:in `each'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer/array_serializer.rb:5:in `each'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer/adapter/json.rb:20:in `map'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer/adapter/json.rb:20:in `block in serializable_hash'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer.rb:224:in `call'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer.rb:224:in `block in each_association'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer.rb:208:in `each'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer.rb:208:in `each_association'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer/adapter/json.rb:17:in `serializable_hash'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer/adapter/json.rb:9:in `block in serializable_hash'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer/array_serializer.rb:5:in `each'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer/array_serializer.rb:5:in `each'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer/adapter/json.rb:9:in `map'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer/adapter/json.rb:9:in `serializable_hash'
  active_model_serializers (0.10.0.rc1) lib/active_model/serializer/adapter.rb:23:in `as_json'
  activesupport (4.2.0) lib/active_support/json/encoding.rb:34:in `encode'
  activesupport (4.2.0) lib/active_support/json/encoding.rb:21:in `encode'
  activesupport (4.2.0) lib/active_support/core_ext/object/json.rb:37:in `to_json_with_active_support_encoder'
  actionpack (4.2.0) lib/action_controller/metal/renderers.rb:116:in `block in <module:Renderers>'
  active_model_serializers (0.10.0.rc1) lib/action_controller/serialization.rb:49:in `block (2 levels) in <module:Serialization>'
  actionpack (4.2.0) lib/action_controller/metal/renderers.rb:45:in `block in _render_to_body_with_renderer'
  /home/kaspar/.rbenv/versions/2.2.0/lib/ruby/2.2.0/set.rb:283:in `each_key'
  /home/kaspar/.rbenv/versions/2.2.0/lib/ruby/2.2.0/set.rb:283:in `each'
  actionpack (4.2.0) lib/action_controller/metal/renderers.rb:41:in `_render_to_body_with_renderer'
  actionpack (4.2.0) lib/action_controller/metal/renderers.rb:37:in `render_to_body'
  actionpack (4.2.0) lib/abstract_controller/rendering.rb:25:in `render'
  actionpack (4.2.0) lib/action_controller/metal/rendering.rb:16:in `render'
  actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:41:in `block (2 levels) in render'
  activesupport (4.2.0) lib/active_support/core_ext/benchmark.rb:12:in `block in ms'
  /home/kaspar/.rbenv/versions/2.2.0/lib/ruby/2.2.0/benchmark.rb:303:in `realtime'
  activesupport (4.2.0) lib/active_support/core_ext/benchmark.rb:12:in `ms'
  actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:41:in `block in render'
  actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:84:in `cleanup_view_runtime'
  activerecord (4.2.0) lib/active_record/railties/controller_runtime.rb:25:in `cleanup_view_runtime'
  actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:40:in `render'
  responders (2.1.0) lib/action_controller/responder.rb:258:in `display'
  responders (2.1.0) lib/action_controller/responder.rb:212:in `api_behavior'
  responders (2.1.0) lib/action_controller/responder.rb:191:in `rescue in to_format'
  responders (2.1.0) lib/action_controller/responder.rb:185:in `to_format'
  responders (2.1.0) lib/action_controller/responder.rb:163:in `respond'
  responders (2.1.0) lib/action_controller/responder.rb:156:in `call'
  responders (2.1.0) lib/action_controller/respond_with.rb:203:in `respond_with'
  app/controllers/users_controller.rb:73:in `feed'
  actionpack (4.2.0) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
  actionpack (4.2.0) lib/abstract_controller/base.rb:198:in `process_action'
  actionpack (4.2.0) lib/action_controller/metal/rendering.rb:10:in `process_action'
  actionpack (4.2.0) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
  activesupport (4.2.0) lib/active_support/callbacks.rb:117:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:117:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:151:in `block in halting_and_conditional'
  activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
  activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
  activesupport (4.2.0) lib/active_support/callbacks.rb:151:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:151:in `block in halting_and_conditional'
  activesupport (4.2.0) lib/active_support/callbacks.rb:234:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:234:in `block in halting'
  activesupport (4.2.0) lib/active_support/callbacks.rb:234:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:234:in `block in halting'
  activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
  activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
  activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
  activesupport (4.2.0) lib/active_support/callbacks.rb:92:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:92:in `_run_callbacks'
  activesupport (4.2.0) lib/active_support/callbacks.rb:734:in `_run_process_action_callbacks'
  activesupport (4.2.0) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (4.2.0) lib/abstract_controller/callbacks.rb:19:in `process_action'
  actionpack (4.2.0) lib/action_controller/metal/rescue.rb:29:in `process_action'
  actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
  activesupport (4.2.0) lib/active_support/notifications.rb:164:in `block in instrument'
  activesupport (4.2.0) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  activesupport (4.2.0) lib/active_support/notifications.rb:164:in `instrument'
  actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
  actionpack (4.2.0) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
  activerecord (4.2.0) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  actionpack (4.2.0) lib/abstract_controller/base.rb:137:in `process'
  actionview (4.2.0) lib/action_view/rendering.rb:30:in `process'
  actionpack (4.2.0) lib/action_controller/metal.rb:195:in `dispatch'
  actionpack (4.2.0) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
  actionpack (4.2.0) lib/action_controller/metal.rb:236:in `block in action'
  actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:73:in `call'
  actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:73:in `dispatch'
  actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:42:in `serve'
  actionpack (4.2.0) lib/action_dispatch/journey/router.rb:43:in `block in serve'
  actionpack (4.2.0) lib/action_dispatch/journey/router.rb:30:in `each'
  actionpack (4.2.0) lib/action_dispatch/journey/router.rb:30:in `serve'
  actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:802:in `call'
  warden (1.2.3) lib/warden/manager.rb:35:in `block in call'
  warden (1.2.3) lib/warden/manager.rb:34:in `catch'
  warden (1.2.3) lib/warden/manager.rb:34:in `call'
  rack (1.6.1) lib/rack/etag.rb:24:in `call'
  rack (1.6.1) lib/rack/conditionalget.rb:25:in `call'
  rack (1.6.1) lib/rack/head.rb:13:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/flash.rb:260:in `call'
  rack (1.6.1) lib/rack/session/abstract/id.rb:225:in `context'
  rack (1.6.1) lib/rack/session/abstract/id.rb:220:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/cookies.rb:560:in `call'
  activerecord (4.2.0) lib/active_record/query_cache.rb:36:in `call'
  activerecord (4.2.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:647:in `call'
  activerecord (4.2.0) lib/active_record/migration.rb:378:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:88:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:88:in `_run_callbacks'
  activesupport (4.2.0) lib/active_support/callbacks.rb:734:in `_run_call_callbacks'
  activesupport (4.2.0) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (4.2.0) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/reloader.rb:73:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/remote_ip.rb:78:in `call'
  better_errors (2.1.1) lib/better_errors/middleware.rb:84:in `protected_app_call'
  better_errors (2.1.1) lib/better_errors/middleware.rb:79:in `better_errors_call'
  better_errors (2.1.1) lib/better_errors/middleware.rb:57:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.2.0) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.2.0) lib/rails/rack/logger.rb:20:in `block in call'
  activesupport (4.2.0) lib/active_support/tagged_logging.rb:68:in `block in tagged'
  activesupport (4.2.0) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (4.2.0) lib/active_support/tagged_logging.rb:68:in `tagged'
  railties (4.2.0) lib/rails/rack/logger.rb:20:in `call'
  quiet_assets (1.1.0) lib/quiet_assets.rb:27:in `call_with_quiet_assets'
  actionpack (4.2.0) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.6.1) lib/rack/methodoverride.rb:22:in `call'
  rack (1.6.1) lib/rack/runtime.rb:18:in `call'
  activesupport (4.2.0) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
  rack (1.6.1) lib/rack/lock.rb:17:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/static.rb:113:in `call'
  rack (1.6.1) lib/rack/sendfile.rb:113:in `call'
  railties (4.2.0) lib/rails/engine.rb:518:in `call'
  railties (4.2.0) lib/rails/application.rb:164:in `call'
  passenger (5.0.7) lib/phusion_passenger/rack/thread_handler_extension.rb:89:in `process_request'
  passenger (5.0.7) lib/phusion_passenger/request_handler/thread_handler.rb:149:in `accept_and_process_next_request'
  passenger (5.0.7) lib/phusion_passenger/request_handler/thread_handler.rb:110:in `main_loop'
  passenger (5.0.7) lib/phusion_passenger/request_handler.rb:414:in `block (3 levels) in start_threads'
  passenger (5.0.7) lib/phusion_passenger/utils.rb:111:in `block in create_thread_and_abort_on_exception'

The error only occurs when I have an array of mediums. When I just query a single medium and use the same serializer, then the error is not there.

The image_video_file_name and the rest of similar attributes all exist in the database and are useable inside of ruby code. Also when I query a single medium, I can see all of these attributes.

What exactly is wrong here? It used to work with 0.9.x but I am using 0.10.0 now and for some reason it just does not want to work now.

@joaomdmoura joaomdmoura added this to the 0.10 milestone May 15, 2015
@Veske
Copy link
Author

Veske commented May 16, 2015

Any idea on how to work around this nicely? I added the methods that it was throwing error about into my Comment model. Now it will pass without errors. But my Comment should not contain thoes attributes at all what it is trying to put into it.

@groyoh
Copy link
Member

groyoh commented May 17, 2015

This is indeed bug due to these two lines here and here. In the first line, the ArraySerializer option contains :serializer => MediumSerializer and is passed to your MediumSerializer. This has basically no effect at this point. But then at the second line, the options hash will contains :serializer => MediumSerializer and is passed to the association serializer which is an ArraySerializer. So the serializer will serialize your comments using MediumSerializer instead of CommentSerializer.

Workaround -> Specify your association serializer, e.g.:

class MediumSerializer < ActiveModel::Serializer
  has_many :comments, serializer: CommentSerializer
end

Fix -> change this line to:

serializer_class.new(object, options.except(:serializer))

@Veske
Copy link
Author

Veske commented May 17, 2015

Thank you for the response! I hope this will get fixed soon. Will go with the workaround for now.

groyoh pushed a commit to groyoh/active_model_serializers that referenced this issue May 17, 2015
groyoh pushed a commit to groyoh/active_model_serializers that referenced this issue May 17, 2015
@groyoh groyoh mentioned this issue May 17, 2015
joaomdmoura added a commit that referenced this issue May 18, 2015
Avoiding the serializer option when instantiating a new one for ArraySerializer Fixed #911
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants