Opalとは
Opalは、Ruby => JavaScriptのコンパイラです。
HTML内に埋め込んだRubyのコードを走らせるパーサーもあり、
<script type="text/ruby">
puts 'hello'
</script>
みたいな形で試すことも簡単に出来ます。
opal-railsを使えば、JavaScriptのアセットを全てRubyで書くことが出来るようになるので、よりPure Rubyなプロジェクトを作れます。
こちらのリポジトリの説明には**「Bringing Ruby to Rails」**なんて書かれていたりして、知らない人が見たら何がなんだかわからないだろうなと思われます…(笑)
Opalを使ったRailsアプリケーションを作ってみる
rails new で Opalを指定すると、必要なgemが入った状態でプロジェクトが生成されます。
rails new <app-name> --javascript=opal
続いて、下記のいくつかの設定を行う必要があります。
-
config/application.rb
へ指定されたパラメータの追加 -
app/assets/javascripts/application.js
をapplication.js.rb
へ差し替え
詳細はopal-railsのページを参照ください。
コントローラを生成する
ここでは、仮にコントローラ名をexamples
として生成します。
rails generate controller examples
コントローラを作ると、assets/javascripts
内に、examples_view.js.rb
が生成されます。
このファイルは必ず複数形で生成されるようなので、複数形でコントローラ名を指定した方がサンプルを動かす分には楽そうです。
自動生成されたファイルを見てみる
下記のファイルが生成されました。
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use Opal in this file: http://opalrb.org/
#
#
# Here's an example view class for your controller:
#
class ExamplesView
def initialize(selector = 'body.controller-examples', parent = Element)
@element = parent.find(selector)
setup
end
attr_reader :element
def setup
# Put here the setup for the view behavior
say_hello_when_a_link_is_clicked
end
def say_hello_when_a_link_is_clicked
all_links.on :click do |event|
# Use prevent_default to stop default behavior (as you would do in jQuery)
# event.prevent_default
puts "Hello! (You just clicked on a link: #{event.current_target.text})"
end
end
private
def all_links
@all_links ||= element.find('a')
end
end
内容としては、
-
body.controller-examples
を取ってくる - body内の
<a>
要素を全部取ってくる -
<a>
要素をクリックしたら、コンソールに"Hello!"と表示する
と言った感じのことを行うclassのようです。
event.prevent_default
のコメントを外すとリンククリック時の画面遷移が無くなりますが、今回のサンプルではリンク先を#にするので、外しても外さなくてもどっちでも良いです。
もろもろ準備する
1.ビューを用意する
<%= link_to 'Click me!', '#' %>
2.コントローラにアクションを追加する
class ExamplesController < ApplicationController
def index
end
end
3.ルートを通す
Rails.application.routes.draw do
root 'examples#index'
end
4.bodyのclassにコントローラ名が入るようにする
<body class="<%= "controller-#{controller_name}" %>">
<%= yield %>
</body>
ExamplesViewのインスタンスを作る
もう一度、先ほど自動生成されたexamples_view.js.rb
を見てみると、classの宣言のみでインスタンスを作っていないので、ページの読み込み完了時にインスタンス生成のコードが発火するようにします。
Document.ready? do
ExamplesView.new
end
こちらのDocument.ready?
は、大体お察しだと思いますが、jQueryの$(document).ready
です。
opal-jqueryはopal_ujsに含まれているので、このファイル中でrequireする必要は無いようです。
動く

実用性とか
もうちょっと使ってみて考えてみますが、
DOM操作は基本opal-jqueryで行うことになりそうなので、普通のjQueryを使い慣れていない身としては、結局jQueryのAPIドキュメント読む所からスタートなのか…と若干重い気分になります。
他のJSラッパーについては、Awesome Opal眺めてみたら色々見付かりそうです。
Reactrbとかあったりするようなので、ここから試してみようと思います。
Voltと言う、表・裏共にRubyで書けることを売りにしているフレームワークもあって、こちら人気っぽいので試してみたいです。