Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asset Pipeline in Active Model Serializers

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?

like image 848
Levi McCallum Avatar asked Dec 03 '13 20:12

Levi McCallum


2 Answers

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
like image 139
zznq Avatar answered Oct 06 '22 00:10

zznq


(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.

like image 36
m_x Avatar answered Oct 05 '22 22:10

m_x