Skip to content

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

Open
veloper opened this Issue Aug 21, 2012 · 9 comments

5 participants

@veloper
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.

Scenario

URL

/api/v1/clients.csv?_include=2

Controller

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 
  end

  def include?
    # logic to determine include depth
  end

end

Problem

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 (https://github.com/nesquena/rabl/blob/master/lib/rabl/engine.rb#L6)

Looking at the Engine class it appears to set the format here: https://github.com/nesquena/rabl/blob/master/lib/rabl/engine.rb#L28 ...which calls this method here: https://github.com/nesquena/rabl/blob/master/lib/rabl/engine.rb#L211 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
  end

  def include?
    @controller.include?
  end
end

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

Pointers, thoughts, opinions?

Thanks :)

@nesquena
Owner

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
veloper commented Aug 21, 2012

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

@nesquena
Owner

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

@veloper
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
Collaborator
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)
@mateusmaso

Getting the same problem here :/

@databyte
Collaborator

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

@databyte databyte was assigned Nov 20, 2012
@sockmonk
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
Owner
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.