#297 Running JavaScript in Ruby pro
Sometimes logic needs to be shared between the server-side (Ruby) and the client-side (JavaScript). Here I show how to run JavaScript directly in Ruby through ExecJS and therubyracer.
- Download:
- source code
- mp4
- m4v
- webm
- ogv
Great screencast.
It would be cool if we could use helpers from Rails (number_to_currency etc.) in JS :( bu t that is not possible.
I think this a bit of a stretch... while there might be some situations when this kind of mojo would be helpful I don't it should be normal practice. In fact it breaks the MVC somewhat. What I normally do is one of two things: either app is fully JS–based and logic is processed via JS while rails acts as server side model or use ajax to fetch pre–processed data and only display them via js code.
I concur.
I find this to be a pretty nice proof of concept, but I'd rather skip JavaScript validation entirely than going down this route.
+1
+1
+1
+1
+1
+1
I agree. 'Stretch', but cool at the same time.
This technique buys you two things:
However, the bridge is completely closed because JS runtimes are not equivalent. For example, how do you deal with timezones (you're making a
new Date
which means you can have some weird ordering issues if the day is different depending on whether the server/client are in a different zone.Really cool though :-)
+1 still very interesting proof of concept
Re: memory leaks, it seems like it would be easy to attach a counter to the JS context and say, every 1000 uses, go ahead and dump the existing context and re-build a new one. Inelegant, but effective! Just wanted to throw that idea out there.
what's the benefit to using therubyracer (V8) vs therubyrhino (mozilla)?
therubyracer is api compatible with therubyrhino but doesn't require python to be installed to compile.
Just a heads up, you don't need to do this:
For the Product class to be globally available. You can combine that into the actual definition of the class, like such:
Nice tip
Thanks, Mark. Very nice tip.
Very nice stuff Ryan !
You always are a precursor ;)
But what I'm asking is : to push further, why not using node.js and being able to transparently share code between the client and the server ?
Don't make me wrong, I love ruby and want to continue to work with rails !
Thanks for the great screencast!
When it turns to such things as DRY concept between Server <-> Client, I think about DSLs. Ruby is a great language for embedded DSLs, so why not to write a new DSL to write (for example) validation code with and then generate and execute from that DSL-code:
- Ruby no the server side
- JS on the client side
This DSL could be exandable by rails apps to allow any complexy operation. On the other hand, such DSL could also provide the natural limitations to users. For example, you can't ready access dom attributes or data base from such "DRY" code.
What are you think?
Hmmm, some good points made in these comments. And I have to say I'm leaning towards Sergey Kuleshov's comment. This is a very cool screencast, but I'm not sure I'd go this far in a production project.
I like that you're showing us Coffeescript usage too Ryan, it's lowering the barrier for me, but I've got to say, I still prefer straight Javascript. I still find Coffeescript very hard to read. Ultimately, I think I'd love to be able to write my Javascript in Ruby.
The similarity of Ruby's new hash syntax is bringing the two closer, and this is something I adopted only this week. Yeah, I know... slow on the uptake.
Hi,
Probably a newbie question, but I want to be sure...Can I use ExecJS to execute JS code on the client side?
Thanks!
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).
10x Matthiew,
I'll try to be more specific. I need to execute some JS snippet on he client side (actually it's executing google analytics code), but I want to run it from a controller on my app (the controller action redirects automatically without rendering html, don't ask why.. :-)
So, I'm not sure whether ExecJS + therubyracer can do that
Thanks.
This is the first time I've ever seen "caching" implemented by storing something in Thread.current...is this somewhat of a standard practice? Anyone have any links to more explanation of this technique?
Wouldn't it make more sense to create a $JsProduct class object in an initializer and then call new on $JsProduct in the for_mustache method?
config/initializers/js_product.rb
models/product.rb