RailsCasts Pro episodes are now free!
Learn more or hide this
GitHub User: mguillemot
Usually, your client side will be a web browser that can execute JS code without any third-party library, so ExecJS is not needed in this case (and wouldn't work, since ExecJS needs a Ruby interpreter, that is not available in any standard web browser).
In this case, I think Ryan just suggested you would use a Prawn::Document object inside your OrderPdf class, instead of inheriting from it. So for example, you would change:
class OrderPdf < Prawn::Document
text "Order goes here"
@pdf = Prawn::Document.new
@pdf.text "Order goes here"
(or use the delegate method mentionned by syath instead of writing your own render method)
In general, prefer composition to inheritance is considered good engineering practice because you control more tightly what your class exposes when you "use" an object rather than inheriting from it, so you have less surprises in the future.
For example, if a new version of Prawn renames the render function to render_document, you can just modify your own render method to use the new render_document one, instead of having to track every usage of render in your application. Or if you want to scrap Prawn and use another library, you can probably just modify your OrderPdf without rewriting a single line outside of it.
That's what we mean when we say that composition offer better encapsulation than inheritance.
Also means you could re-use the same JS file with another project. For example if you build a merchant hosting site where each of your users can create their own merchant site hosted by you, you could change easily who the payment is going to while using the same JS file for everyone.
Some peculiarities of Ruby's parser (nothing to do with Rails). Without self, it would think you are trying to assign a local stripe_customer_token variable instead of using the implicitly defined self.stripe_customer_token= attribute writer.
That would likely trigger a Stripe::InvalidRequestError when trying to Stripe::Customer.create( card: stripe_card_token) with your faked stripe_card_token, and thus prevent saving the subscription record.
Stripe::Customer.create( card: stripe_card_token)