10

I'm attempting to include an image asset pipeline url in my model serializer output by including ActiveView::Helpers:

class PostSerializer < ActiveModel::Serializer
  include ActiveView::Helpers

  attributes :post_image

  def post_image
    image_path "posts/#{object.id}"
  end
end

The result is /images/posts/{id} rather than a valid path to the asset pipeline path, ie. /assets/images/posts/{id}. How can I include valid asset pipeline paths in my serializer output?

stillmotion
  • 4,608
  • 4
  • 30
  • 36
  • possible duplicate of [Access Asset Path from Rails Controller](http://stackoverflow.com/questions/7827078/access-asset-path-from-rails-controller) – stillmotion Dec 03 '13 at 20:59

3 Answers3

9

Maybe this could work:

def post_image
  _helpers = ActionController::Base.helpers
  _helpers.image_url "posts/#{object.id}"
end
6

(Very) late to the party, but you can solve the problem by adding this to your ApplicationController :

serialization_scope :view_context

and then in the serializer :

def post_image
  scope.image_url('my-image.png')
end

Explanation : When your controller instanciates a serializer, it passes a scope (context) object along (by default, the controller itself I think). Passing the view_context allows you to use any helper that you would be able to use in a view.

m_x
  • 12,357
  • 7
  • 46
  • 60
2

So I have been struggling with this for a little bit today. I found a slightly less then ideal solution. The ActionController::Base.helpers solution didn't work for me.

This is certainly not the most optimal solution. My thinking is that the proper solution might be to add a 'set_configs' initializer to ActiveModelSerializer.

The ActionView::Helpers::AssetUrlHelper utilizes a function called compute_asset_host which reads config.asset_host. This property looks to be set in railtie initializers for ActionViews and ActionControllers. ActionController::RailTie

So I ended up subclassing the ActiveModel::Serializer and setting the config.asset_host property in the constructor, like so.

class BaseSerializer < ActiveModel::Serializer
  include ActiveSupport::Configurable
  include AbstractController::AssetPaths
  include ActionView::Helpers::AssetUrlHelper

  def initialize(object, options={})
    config.asset_host = YourApp::Application.config.action_controller.asset_host

    super
  end
end

This got me most of the way. These helpers methods also use a protocol value; it can be passed in as a param in an options hash, a config variable, or read from the request variable. so I added a helper method in my BaseSerializer to pass the correct options along.

def image_url(path)
  path_to_asset(path, {:type=>:image, :protocol=>:https})
end
zznq
  • 400
  • 1
  • 15