旧ブログ(ISSEN)から移行しました

【Rails7】Stimulusの命名規則について知ろう!

【Rails7】Stimulusの命名規則について知ろう!

西原月熙
西原月熙8分で読めます

はじめに

こんにちは、株式会社TOKOSのツキヤです!
今回はRails7でJavaScriptを扱う時にデファクトスタンダードとなっているStimulusについて、様々な命名規則について深ぼって解説します!
自分がStimulusを使う時につまずいたポイント等を盛り込んでいますので、お役に立てると幸いです😎

Stimulusとは

その前にStimulusについて超簡単に説明します!
Stimulusとは、Rails(7)がデフォルトで組み込んでいるJavaScriptのフレームワークです。HTMLのdata属性等を使って簡単にアニメーション等を実装するためのモノです。JavaScriptにそこまで詳しくなくても実装できるのが利点です!

詳しい説明や導入方法等は別の記事に記載していますので、気になる方はこちらも読んでみてください🙏

【Rails7】Stimulus入門! | 概要 ~ 使い方まで詳しく解説

Rails 7で標準となったStimulusの概要から実践的な使い方まで詳しく解説。Hotwireの構成要素としての位置づけ、導入方法、data属性を使ったDOM操作の書き方をサンプルコード付きで紹介します。

Stimulusの"命名規則"とは?

さて、早速Stimulusの命名規則について解説しようと思います!
本記事において、Stimulusにおける命名規則は以下のモノを決める時のルールとします!

  • controller名(+ import名、ファイル名)
  • target
  • メソッド名

大きくは上記3つ程に分類できます!
それぞれについて、実際に使用するまでにJavaScript側とHTML側の記述が必要になります!

公式サイトを基にしてRailsバージョンの解説をします!
(以下hello_controller.jsとして解説します)

controller名(+ import名、ファイル名)

これは、app/javascript/controllers配下にある、**_controller.jsファイル名自体と、app/javascript/controllers/index.jsで呼び出すimport名です!

app/javascript/controllers/index.js
// This file is auto-generated by ./bin/rails stimulus:manifest:update
// Run that command whenever you add a new controller or create them with
// ./bin/rails generate stimulus controllerName
 
import { application } from "./application"
 
import HelloController from "./hello_controller"
application.register("hello", HelloController)

上記例のように、7,8行目あたりで定義するものですね!

HTML側では、以下のように指定します!

index.html.erb
<div data-controller="hello">
  <input data-hello-target="name" type="text" />
 
  <button data-action="click->hello#greet">Greet</button>
 
  <span data-hello-target="output"> </span>
</div>

この記述でそもそものHTMLとJavaScriptの意思疎通ができるのでしたね!

target

これは、DOM操作をしたい対象について宣言するものですね!
JavaScript側の記載箇所は、hello_controller.jsファイル内に書く記述です。

hello_controller.js
// hello_controller.js
import { Controller } from "stimulus"
 
export default class extends Controller {
  static targets = ["name", "output"]
 
  greet() {
    this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!`
  }
}

5行目のように定義しておけば、document.getElementByIdで取得したようになり、8行目のように呼び出せます!

HTML側では、以下のように指定します!

index.html.erb
<div data-controller="hello">
  <input data-hello-target="name" type="text" />
 
  <button data-action="click->hello#greet">Greet</button>
 
  <span data-hello-target="output"> </span>
</div>

メソッド名

これは、実際に動作を行った時のロジック内容を記載するものですね!
JavaScript側の記載箇所は、

hello_controller.js
// hello_controller.js
import { Controller } from "stimulus"
 
export default class extends Controller {
  static targets = ["name", "output"]
 
  greet() {
    this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!`
  }
}

7 ~ 9行目の記述です!

HTML側では、

index.html.erb
<div data-controller="hello">
  <input data-hello-target="name" type="text" />
 
  <button data-action="click->hello#greet">Greet</button>
 
  <span data-hello-target="output"> </span>
</div>

4行目のような形です!
それでは、これらをどのように命名する必要があるのか解説していきます!

各命名規則について

上記3種類の各命名規則については、ぶっちゃけ公式サイトを見たらほとんど分かるとは思うのですが、1つだけすぐに分からないことがあったので本記事ではその内容について触れていきます!

それは、「複数単語」の場合です!
公式サイトの例では、hello_controller.jsとなっており、targetやメソッドも単語が1つで構成されているのでこのあたりが分からなかったです。
詳しくは、公式サイト内等を色々たどれば書いてあるのですが、本記事では抜粋して分かりやすくまとめます😎

controller名(+ import名、ファイル名)

まずはcontroller名です!
controllerについてはファイル名、index.js内のimport名やHTMLと色々記述する箇所があるのですが、JavaScript側については簡単にルール通りに記述する方法があります!

それはrails g stimulusコマンドを使うことです!
例えば、rails g stimulus helloとターミナルに打つと、、

app/javascript/controllers/index.js
// This file is auto-generated by ./bin/rails stimulus:manifest:update
// Run that command whenever you add a new controller or create them with
// ./bin/rails generate stimulus controllerName
 
import { application } from "./application"
 
import HelloController from "./hello_controller"
application.register("hello", HelloController)
app/javascript/controllers/hello_controller.js
import { Controller } from "@hotwired/stimulus"
 
// Connects to data-controller="hello"
export default class extends Controller {
  connect() {}
}

上記のように、index.jsに追記がされつつ、hello_controller.jsファイルが作成されます!
これにより、実質的に命名規則については特に意識しなくて良さそうですね!

とは言いつつ、気になるとは思いますので一応解説します!
ファイル名については、スネークケースで、import名については、パスカルケースです!

HTML側については、上記のhello_controller.jsの3行目に書いてあるように、

index.html.erb
<div data-controller="hello">
  <!-- 色々 -->
</div>

このように書けばOKです!

命名規則の一般用語について

次に複数単語のcontrollerを作る時の説明をします!
こちらについても簡単で、rails g stimulus my_helloとコマンドを打つだけです!(スネークケースでもパスカルケースでもOK)
同様に確認してみると、

app/javascript/controllers/index.js
// This file is auto-generated by ./bin/rails stimulus:manifest:update
// Run that command whenever you add a new controller or create them with
// ./bin/rails generate stimulus controllerName
 
import { application } from "./application"
 
import HelloController from "./hello_controller"
application.register("hello", HelloController)
 
import MyHelloController from "./my_hello_controller"
application.register("my-hello", MyHelloController)
app/javascript/controllers/my_hello_controller.js
import { Controller } from "@hotwired/stimulus"
 
// Connects to data-controller="my-hello"
export default class extends Controller {
  connect() {}
}

同じように、それぞれの命名規則のルールごとに自動生成されます!

気を付けて欲しいのが、HTML側での呼び出しです!
こちらはケバブケースになっています!

index.html.erb
<div data-controller="my-hello">
  <!-- 色々 -->
</div>

my-helloのように、ハイフンつなぎで書いてください!

以上でcontrollerの解説を終わります!
基本的に自動生成されるので問題無かったのでは無いでしょうか?

ツキヤツキヤ

僕は最初このようなコマンドがあることを知らなくて全部手動で作っていて大変でした😱

target

targetに関して結論から、JavaScriptもHTMLもキャメルケースです!!
公式サイトの例のtarget名だけ複数単語に変更したバージョンが下記になります!

hello_controller.js
// hello_controller.js
import { Controller } from "stimulus"
 
export default class extends Controller {
  static targets = ["myName", "myOutput"]
 
  greet() {
    this.myOutputTarget.textContent = `Hello, ${this.myNameTarget.value}!`
  }
}
index.html.erb
<div data-controller="hello">
  <input data-hello-target="myName" type="text" />
  <!-- 略 -->
  <span data-hello-target="myOutput"> </span>
</div>

HTML側では、data-**-target="変数"のように左辺は記述します!
**の部分には、controller名が入ります!
ここで気になるのが、controller名が複数単語の場合です🤔
この場合、**の部分はケバブケースで記載してください!

index.html.erb
<div data-controller="my-hello">
  <input data-my-hello-target="myName" type="text" />
  <!-- 略 -->
  <span data-my-hello-target="myOutput"> </span>
</div>

これで、controller名が複数単語かつtargetが複数単語のパターンも問題無いですね✨

メソッド名

最後にメソッドです。

hello_controller.js
// hello_controller.js
import { Controller } from "stimulus"
 
export default class extends Controller {
  static targets = ["myName", "myOutput"]
 
  myGreet() {
    this.myOutputTarget.textContent = `Hello, ${this.myNameTarget.value}!`
  }
}

まず、JavaScriptはキャメルケースです!

index.html.erb
<div data-controller="hello">
  <input data-hello-target="myName" type="text" />
 
  <button data-action="click->hello#myGreet">Greet</button>
 
  <span data-hello-target="myOutput"> </span>
</div>

HTML側は、data-action="アクション->コントローラー名#メソッド名"のようになります!
アクションは、click以外にも、mouseover等様々なものが使えるので気になる人は下記リンクが参考になったので見てみてください

【javascript】addEventListenerイベントまとめ - Qiita

はじめに JavaScriptのevent(マウスクリックやブラウザを開いた時など)指定した関数を呼び出すことがよくありイベント処理を実現する仕組みするため、addEventListener()が用意されています。 使えない(IE対応できない、一部実装状況不明)場合もあり...

qiita.com

メソッドの呼び出しについても、controllerが複数単語の場合はHTML側でケバブケースを指定してください!

index.html.erb
<div data-controller="my-hello">
  <input data-my-hello-target="myName" type="text" />
 
  <button data-action="click->my-hello#myGreet">Greet</button>
 
  <span data-my-hello-target="myOutput"> </span>
</div>

HTML側では、controllerは全てケバブケースという覚え方で問題無いです💪

終わりに

ここまでを読んでいただければ分かるのですが、命名規則なんてものは知っているか知らないかだけですね!
僕はこれを調べるのにかなり時間をかけてしまったので、この記事を見て時短をしてくれる人がいれば嬉しい限りです✨

Stimulusについてこの本にも解説が載っているので、よければ読んでみてください🥳

この記事を書いた人

西原月熙
西原月熙

TOKOSのテックリード。上流工程からコーディング、インフラ系まで色々やっている器用貧乏です。最近は特にフロントエンドのキャッチアップに力を入れています💪 好きな音楽はボーカロイドです🤖