I'm using Rabl to generate XML output in a rake task:
xml = Rabl.render @listings, 'feeds/listings', :format => :xml
# do stuff with xml
However, I need to use multiple helper methods in the rabl view file referenced, and I keep getting a NoMethodError
as I expected from the answer to this question.
I tried using extends
and include
in the class used by the rake task but I still get the same error on the helper methods:
require "#{Rails.root}/app/helpers/feeds_helper.rb"
class SerializeData
extends FeedsHelper
def perform
xml = Rabl.render @listings, 'feeds/listings', :format => :xml
# do stuff with xml
end
end
My question is: is there any way to use helper methods in rabl view files generated in this way? (or at least in a way that I can still render them as a string in a rake task?) The helper methods are used many, many times to correctly format various data per fixed requirements, so it would be very difficult to remove them entirely.
I ended up with a monkey-patchy solution.
I noticed that the NoMethodFound
error came from an instance of the Rabl::Engine
class, so I included the needed routing and helper methods in that class and was then able to access them:
require "#{Rails.root}/app/helpers/feeds_helper.rb"
...
class Rabl::Engine
include Rails.application.routes.url_helpers
include FeedsHelper
end
Also note that the URL host needs to be set if using url
in addition to path
helpers (e.g. root_url
and root_path
):
Rails.application.routes.default_url_options[:host] = "www.example.com"
I would definitely prefer a non-monkey-patch solution or at least one where helpers could be included as needed depending on the controller of the action rendered. I'll wait to accept this to see if anyone can come up with such an answer.
You can pass in a scope object with the scope parameter. So if you have access to an object with the helper included, like when in the view context, then you can pass that eg:
<%= Rabl::Renderer.json(object_to_render, 'api/v1/object/show', view_path: 'app/views', scope: self).html_safe%>
So outside of the view context you'd need to pass in a custom object with the helpers included to make this clean. eg
class RakeScope
include FeedHelper
end
Rabl::Renderer.json(object_to_render, 'api/v1/object/show', view_path: 'app/views', scope: RakeScope.new() )
I've not tried the second option but the first works great.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With