Add Opal to your Gemfile:
gem 'opal-rails'
Or to start off with Opal when you build your new Rails app:
rails new <app-name> --javascript=opal
// app/assets/application.js.rb
//= require opal
//= require opal_ujs
//= require turbolinks
//= require_tree .
Opal requires are forwarded to the Asset Pipeline at compile time (similarly to what happens for RubyMotion). You can use either the .rb
or .opal
extension:
# app/assets/javascripts/greeter.js.rb
puts "G'day world!" # check the console!
# Dom manipulation
require 'opal-jquery'
Document.ready? do
Element.find('body > header').html = '<h1>Hi there!</h1>'
end
You can use it for your views too, it even inherits instance and local variables from actions:
# app/controllers/posts_controller.rb
def create
@post = Post.create!(params[:post])
render type: :js, locals: {comments_html: render_to_string(@post.comments)}
end
Each assign is filtered through JSON so it's reduced to basic types:
# app/views/posts/create.js.opal
post = Element.find('.post')
post.find('.title').html = @post[:title]
post.find('.body').html = @post[:body]
post.find('.comments').html = comments_html
Of course you need to require haml-rails
separately since its presence is not assumed
-# app/views/posts/show.html.haml
%article.post
%h1.title= post.title
.body= post.body
%a#show-comments Display Comments!
.comments(style="display:none;")
- post.comments.each do |comment|
.comment= comment.body
:opal
Document.ready? do
Element.find('#show-comments').on :click do |click|
click.prevent_default
click.current_target.hide
Element.find('.comments').effect(:fade_in)
end
end
Add specs into app/assets/javascripts/spec
:
and then a spec folder with you specs!
# app/assets/javascripts/spec/example_spec.js.rb
describe 'a spec' do
it 'has successful examples' do
'I run'.should =~ /run/
end
end
Then visit /opal_spec
from your app and reload at will.