Netflix / fast_jsonapi

No Longer Maintained - A lightning fast JSON:API serializer for Ruby Objects.
Apache License 2.0
5.07k stars 426 forks source link

Cannot cache serializer with Carrierwave Uploader attribute #379

Open kpheasey opened 5 years ago

kpheasey commented 5 years ago

When caching is enabled on a serializer that has an attribute defined for a Carrierwave Uploader, a TypeError: no _dump_data is defined for class Proc is thrown.

# app.serializers/user_serializer.rb

class UserSerializer
  include FastJsonapi::ObjectSerializer

  set_type :users
  cache_options enabled: true

  attributes :id, :avatar
end
# app/models/user.rb

class User < ApplicationRecord
  mount_uploader :avatar, AvatarUploader
end
# app/uploaders/avatar_uploader.rb

class AvatarUploader
class AvatarUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  version :thumb do
    process resize_to_fill: [300, 300]
    process quality: 85
  end

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def extension_whitelist
    %w[jpg jpeg png]
  end

  def content_type_whitelist
    %r{image/}
  end

  def default_url(*_args)
    ActionController::Base.helpers.asset_path('placeholder.png')
  end

  def exists?
    default_url != url
  end

  def as_json(options = {})
    super.merge(exists: exists?)
  end
end

Here's the trace:

TypeError: no _dump_data is defined for class Proc
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/cache.rb", line 807, in dump
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/cache.rb", line 807, in marshaled_value
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/cache.rb", line 787, in should_compress?
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/cache.rb", line 718, in initialize
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/cache.rb", line 445, in new
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/cache.rb", line 445, in block in write
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/cache.rb", line 663, in block in instrument
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/notifications.rb", line 170, in instrument
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/cache.rb", line 663, in instrument
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/cache.rb", line 444, in write
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/cache.rb", line 697, in save_block_result_to_cache
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/cache.rb", line 323, in fetch
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 67, in record_hash
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 148, in block (3 levels) in get_included_records
  File "/app/vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.0/lib/active_record/relation/delegation.rb", line 41, in each
  File "/app/vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.0/lib/active_record/relation/delegation.rb", line 41, in each
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 132, in block (2 levels) in get_included_records
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 118, in each
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 118, in block in get_included_records
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 116, in each
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 116, in each_with_object
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 116, in get_included_records
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 139, in block (3 levels) in get_included_records
  File "/app/vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.0/lib/active_record/relation/delegation.rb", line 41, in each
  File "/app/vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.0/lib/active_record/relation/delegation.rb", line 41, in each
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 132, in block (2 levels) in get_included_records
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 118, in each
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 118, in block in get_included_records
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 116, in each
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 116, in each_with_object
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/serialization_core.rb", line 116, in get_included_records
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/object_serializer.rb", line 57, in block in hash_for_collection
  File "/app/vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.0/lib/active_record/relation/delegation.rb", line 41, in each
  File "/app/vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.0/lib/active_record/relation/delegation.rb", line 41, in each
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/object_serializer.rb", line 55, in hash_for_collection
  File "/app/vendor/bundle/ruby/2.5.0/gems/fast_jsonapi-1.4/lib/fast_jsonapi/object_serializer.rb", line 31, in serializable_hash
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/core_ext/object/json.rb", line 54, in as_json
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/json/encoding.rb", line 22, in encode
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/json/encoding.rb", line 22, in encode
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/core_ext/object/json.rb", line 41, in to_json
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/renderers.rb", line 157, in block in <module:Renderers>
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/renderers.rb", line 150, in block in _render_to_body_with_renderer
  File "/app/vendor/ruby-2.5.3/lib/ruby/2.5.0/set.rb", line 338, in each_key
  File "/app/vendor/ruby-2.5.3/lib/ruby/2.5.0/set.rb", line 338, in each
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/renderers.rb", line 146, in _render_to_body_with_renderer
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/renderers.rb", line 142, in render_to_body
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/abstract_controller/rendering.rb", line 25, in render
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/rendering.rb", line 36, in render
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/instrumentation.rb", line 46, in block (2 levels) in render
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/core_ext/benchmark.rb", line 14, in block in ms
  File "/app/vendor/ruby-2.5.3/lib/ruby/2.5.0/benchmark.rb", line 308, in realtime
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/core_ext/benchmark.rb", line 14, in ms
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/instrumentation.rb", line 46, in block in render
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/instrumentation.rb", line 87, in cleanup_view_runtime
  File "/app/vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.0/lib/active_record/railties/controller_runtime.rb", line 31, in cleanup_view_runtime
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/instrumentation.rb", line 45, in render
  File "/app/app/controllers/api/v1/projects_controller.rb", line 15, in current
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/basic_implicit_render.rb", line 6, in send_action
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/abstract_controller/base.rb", line 194, in process_action
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/rendering.rb", line 30, in process_action
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/abstract_controller/callbacks.rb", line 42, in block in process_action
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/callbacks.rb", line 109, in block in run_callbacks
  File "/app/vendor/bundle/ruby/2.5.0/gems/react-rails-2.4.4/lib/react/rails/controller_lifecycle.rb", line 31, in use_react_component_helper
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/callbacks.rb", line 118, in block in run_callbacks
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/callbacks.rb", line 136, in run_callbacks
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/abstract_controller/callbacks.rb", line 41, in process_action
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/rescue.rb", line 22, in process_action
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/instrumentation.rb", line 34, in block in process_action
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/notifications.rb", line 168, in block in instrument
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/notifications/instrumenter.rb", line 23, in instrument
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/notifications.rb", line 168, in instrument
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/instrumentation.rb", line 32, in process_action
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/params_wrapper.rb", line 256, in process_action
  File "/app/vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.0/lib/active_record/railties/controller_runtime.rb", line 24, in process_action
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/abstract_controller/base.rb", line 134, in process
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionview-5.2.0/lib/action_view/rendering.rb", line 32, in process
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal.rb", line 191, in dispatch
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal.rb", line 252, in dispatch
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/routing/route_set.rb", line 52, in dispatch
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/routing/route_set.rb", line 34, in serve
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/journey/router.rb", line 52, in block in serve
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/journey/router.rb", line 35, in each
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/journey/router.rb", line 35, in serve
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/routing/route_set.rb", line 840, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/warden-1.2.7/lib/warden/manager.rb", line 36, in block in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/warden-1.2.7/lib/warden/manager.rb", line 35, in catch
  File "/app/vendor/bundle/ruby/2.5.0/gems/warden-1.2.7/lib/warden/manager.rb", line 35, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/rack-2.0.5/lib/rack/tempfile_reaper.rb", line 15, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/rack-2.0.5/lib/rack/etag.rb", line 25, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/rack-2.0.5/lib/rack/conditional_get.rb", line 25, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/rack-2.0.5/lib/rack/head.rb", line 12, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/http/content_security_policy.rb", line 18, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/rack-2.0.5/lib/rack/session/abstract/id.rb", line 232, in context
  File "/app/vendor/bundle/ruby/2.5.0/gems/rack-2.0.5/lib/rack/session/abstract/id.rb", line 226, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/middleware/cookies.rb", line 670, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/middleware/callbacks.rb", line 28, in block in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/callbacks.rb", line 98, in run_callbacks
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/middleware/callbacks.rb", line 26, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/rollbar-2.16.2/lib/rollbar/middleware/rails/rollbar.rb", line 24, in block in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/rollbar-2.16.2/lib/rollbar.rb", line 146, in scoped
  File "/app/vendor/bundle/ruby/2.5.0/gems/rollbar-2.16.2/lib/rollbar/middleware/rails/rollbar.rb", line 22, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/middleware/debug_exceptions.rb", line 61, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/rollbar-2.16.2/lib/rollbar/middleware/rails/show_exceptions.rb", line 22, in call_with_rollbar
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/middleware/show_exceptions.rb", line 33, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/railties-5.2.0/lib/rails/rack/logger.rb", line 38, in call_app
  File "/app/vendor/bundle/ruby/2.5.0/gems/railties-5.2.0/lib/rails/rack/logger.rb", line 26, in block in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/tagged_logging.rb", line 71, in block in tagged
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/tagged_logging.rb", line 28, in tagged
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/tagged_logging.rb", line 71, in tagged
  File "/app/vendor/bundle/ruby/2.5.0/gems/railties-5.2.0/lib/rails/rack/logger.rb", line 26, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/middleware/remote_ip.rb", line 81, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/middleware/request_id.rb", line 27, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/rack-2.0.5/lib/rack/method_override.rb", line 22, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/rack-2.0.5/lib/rack/runtime.rb", line 22, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.0/lib/active_support/cache/strategy/local_cache_middleware.rb", line 29, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/middleware/executor.rb", line 14, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/middleware/static.rb", line 127, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/rack-2.0.5/lib/rack/sendfile.rb", line 111, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_dispatch/middleware/ssl.rb", line 74, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/rack-cors-1.0.2/lib/rack/cors.rb", line 97, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/railties-5.2.0/lib/rails/engine.rb", line 524, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/puma-3.11.4/lib/puma/configuration.rb", line 225, in call
  File "/app/vendor/bundle/ruby/2.5.0/gems/puma-3.11.4/lib/puma/server.rb", line 632, in handle_request
  File "/app/vendor/bundle/ruby/2.5.0/gems/puma-3.11.4/lib/puma/server.rb", line 446, in process_client
  File "/app/vendor/bundle/ruby/2.5.0/gems/puma-3.11.4/lib/puma/server.rb", line 306, in block in run
  File "/app/vendor/bundle/ruby/2.5.0/gems/puma-3.11.4/lib/puma/thread_pool.rb", line 120, in block in spawn_thread
kpheasey commented 5 years ago

Solution was to use a custom attribute convert the uploader to json.

# app.serializers/user_serializer.rb

class UserSerializer
  include FastJsonapi::ObjectSerializer

  set_type :users
  cache_options enabled: true

  attributes :id

  attributes :avatar do |object|
    object.avatar.as_json
  end
end