Skip to content

Forcing a specific :format using Rabl::Renderer.json w/ :scope option set. #315

veloper opened this Issue Aug 21, 2012 · 9 comments

5 participants

veloper commented Aug 21, 2012

I was wondering if there was a way to force the underlying renderer to use a specific format when using Rabl::Renderer when the :scope option is specified.

My views are currently named like so xxxxx.json.rabl and as such need to have a specific :format of json

My views also make use of a helper method defined in the application controller called include? which reads params[:_include] and figures out if a relationship should be included as child node.





class ApplicationController < ActionController::Base

  helper_method :include?
  before_filter :catch_csv

  def catch_csv
    return unless params[:format] == 'csv'
    json = Rabl::Renderer.json(@collection, "#{params[:controller]}/index", :view_path => 'app/views', :scope => self)
    ... parse and turn into CSV 

  def include?
    # logic to determine include depth



With this example I get the following exception...

ActionView::MissingTemplate (Missing partial api/v1/clients/show with {:locale=>[:en], :formats=>[nil], :handlers=>[:erb, :builder, :rabl]}

You'll notice this part :formats=>[nil] -- as "csv" is not a valid format type in (

Looking at the Engine class it appears to set the format here: ...which calls this method here: seemingly checking the scope i passed in.

The problem is that I need the include? helper method to be available to the RABL views, but I don't want the controllers :format to be used in a manual rendering call.

The only solution I've found seems very ugly and wrong to me... but it works...

Ugly Solution

class RablControllerWrapper
  attr_reader :controller
  def initialize(controller)
    @controller = controller

  def include?

json = Rabl::Renderer.json(@collection, "#{params[:controller]}/index", 
  :view_path => 'app/views', 
  :scope =>

Pointers, thoughts, opinions?

Thanks :)


I see, it looks like we might need to tweak rabl to adhere to an explicitly specified format more closely? Since you specified:

Rabl::Renderer.json(@collection, "#{params[:controller]}/index", :view_path => 'app/views', :scope => self)

it follows that it should try and render the format as JSON rather than CSV. I will have to dig in more later to see if this can be fixed easily. Thanks for raising the issue.

veloper commented Aug 21, 2012

Thanks for the quick reply. For now I'll continue on with a wrapper class.


Yeah that was a clever (albeit unfortunate) workaround. Hopefully we can fix this soon.

veloper commented Aug 21, 2012

Out of curiosity, and if you know off the top of your head, what method/attributes is my wrapper class blocking the library from accessing where it determines the format?

databyte commented Sep 5, 2012

If you want to make a failing test for it, I can tweak it to work because by the looks of it, I would've guessed you can pass in the format and it won't use the request_format method.

Rabl.render(object, template, :view_path => 'app/views', :format => :csv)

Getting the same problem here :/


Anyone want to make a failing test or sample app for me to fix?

@databyte databyte was assigned Nov 20, 2012
sockmonk commented Jan 7, 2013

I'm seeing a very similar issue. It looks like Rabl::Engine#request_format is relying on request_params / context_scope.params to choose the format, rather than @_options[:format] that stores the format the user passed in. Then in Rabl::Partials#fetch_rails_source it uses that for the source_format, with the result that rabl partials aren't found when I try to use them via gon.

I think that Rabl::Engine#request_format should take @_options[:format] into consideration if it's been set. Hope this gets someone closer to fixing this.

nesquena commented Jan 8, 2013

Thanks for tracking that down, hopefully one of us can take a look soon. In the mean time, any pull requests greatly appreciated :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.