.js.erbと.jsの使い分け

2 min read読了の目安(約2100字

商品をお気に入り登録する機能をajaxを利用して実装していた私。
そこで初めて .js.erb と呼ばれる拡張子があることを知りました。

.js.erbとは

一言で言えば、Rubyを埋め込むことのできるjsファイルです。

普通のjsファイルと違う点は、erbタグが使用できること。従って、このファイル形式ではコントローラで定義したインスタンス変数を記述することも可能。

これによってイベント発火時、更新されたインスタンスを呼び出すと同時に、非同期通信を実現する事ができます。

.html.erbと似てる。。。

初見で思ったのは、.html.erbと似ていると言うこと。
.erbの前にある.js.htmlはただ単にファイルの形式を表しているものだと思っていました。

しかし、こちら[1]の記事でその答えを発見。

コントローラは「app/views/コントローラ名/アクション名.リクエストの形式.〇〇」というファイルを探しに行く

つまり、.html.erbの場合は、

  1. クライアントサイドからのhtml形式のリクエスト
  2. MVC一連の流れ
  3. アクションに沿ったビューファイルを表示

一方で、.js.erbの場合は、

  1. クライアントサイドからjs形式のリクエスト
  2. MVC一連の流れ
  3. アクションに沿ってビューファイルを部分的に変更

と言うふうに、リクエストの種類からレスポンスの種類までが異なる。

.js.erb vs (.js & .html)

ここで素朴な疑問。
普通のHTML&JSファイルによる処理と、.js.erbの処理では何が異なる?

https://forum.upcase.com/t/ajax-with-jquery-html-js-vs-js-erb/592

こちらの質問者の方も同じ疑問を持っておられました。

HTML&JSの場合

# create.html.erb

<%= render :partial => 'animation', :locals => { :animation => @animation } %>
# animation_controller.rb

respond_to do |format|
  format.html {render :layout=> false}
end
// animation.js

  $('#new_animation').bind('ajax:success', function(xhr, data, status) {
    $('#animations').append(data);
  });

JS.ERBの場合

# create.js.erb

$lastAnimation = $('<%=j render :partial => 'animation', :locals => { :animation => @animation } -%>')
$('#animations').append($lastAnimation)
# animations_controller.rb

respond_to do |format|
  format.js
end

この2通りのコードを同じ動作を起こしてくれるものですが、どのように使い分けるべきなのか?
明確な答えは見つけられませんでしたが、以下の点がブレークポイントになりそうです。

the single responsibility principle(単一責任の原則)

単一責任の原則とはSOLID原則と呼ばれるオブジェクト指向における5つの設計原則の内の1つ。

「クラスに変更が起こる理由は、一つであるべき。」

js.erbはビューファイル内に.html.erbファイルと共に保存されます。
MVCという仕組みの中での一つの役割であるViewにリクエスト形式の異なるファイルをひとまとめにしてしまっている点がこの原則に背いているのでは...?

と書いてみましたが、よくわかっていません。。ヘルプ!

SOTD

久々にajaxを見直していたところ、.js.erbという新しい選択に出会い世界が広がりました。
明日はこれを使ってお気に入り機能を実装。セッション機能でも試したい。

脚注
  1. Railsで remote: true と js.erbを使って簡単にAjax(非同期通信)を実装しよう! ↩︎