Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
veloper opened this issue Aug 21, 2012 · 9 comments
Open
Assignees
Labels

Comments

@veloper
Copy link

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
Copy link
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
Copy link
Author

veloper commented Aug 21, 2012

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

@nesquena
Copy link
Owner

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

@veloper
Copy link
Author

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
Copy link
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
Copy link

Getting the same problem here :/

@databyte
Copy link
Collaborator

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

@ghost ghost assigned databyte Nov 20, 2012
@sockmonk
Copy link

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
Copy link
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
Labels
Projects
None yet
Development

No branches or pull requests

5 participants