I think shrimp
would be your best bet. Since you need your javascript to be executed a solution that runs PhantomJS
is probably the only way you can go.
Shrimp provides an easy way to add your session cookie in the request. Just to something like the following:
Shrimp::Phantom.new(url, options, {user_session: "a session"})
As you can understand the initializer accepts an options hash and after that a hash with your cookies and their values.
Now the hard part would be to always have a valid session at your server to do the requests. Depending on your session management (e.g. you might have auto expiration) this could be a bit tricky.
EDIT: Adding Andreas's findings about how to hack user session in an Rails application using Devise based on a relevant blog post by the Shrimp creators:
lib/devise/sign_in_interceptor.rb
module Devise
class SignInInterceptor
def initialize(app, opts)
@app = app
@scope =opts[:scope]
@secret = opts[:secret]
@klass = opts[:klass]
end
def call(env)
if user = Rack::Request.new(env).cookies[@secret]
env['warden'].session_serializer.store(@klass.constantize.find(user), @scope)
end
@app.call(env)
end
end
end
config/application.rb
require File.expand_path('../../lib/devise/sign_in_interceptor', __FILE__)
config.middleware.use Devise::SignInInterceptor, { :scope => :user, :klass => 'User',
:secret => "our_very_very_long_secret" }
With this setup we can add a to_pdf method to our resource invoice.rb
def to_pdf
host = Rails.env.production? ? 'www.adjust.io' : 'localhost:3000'
url = Rails.application.routes.url_helpers.reports_url(self, :host => host)
cookie = { 'our_very_very_long_secret' => user_id } #user_id is a instance method on the invoice class
options = { :margin => "1cm"}
res = Shrimp::Phantom.new(url, options, cookie).to_pdf("#{Rails.root}/invoices/invoice_#{self.id}.pdf")
end