Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Railsの技: StimulusJSコントローラからRailsの環境変数にアクセスする(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

Railsの技: StimulusJSコントローラからRailsの環境変数にアクセスする(翻訳)

環境変数はRailsアプリを設定するのによい手段です。Rails.env変数を用いれば、development環境やtest環境やproduction環境に応じて振る舞いを変更できますし、アプリケーションに独自の環境変数を追加してAPIトークンやグローバル設定に使うことも可能です。

StimulusにはHTMLのdata-*属性を読み出すvalues APIがありますが、コントローラを作成するたびに自分の必要なデータをいちいち渡したくないこともあります。

別の方法として、ビューをレンダリングするときに<meta>タグを用いる手法も使えます。<meta>タグを追加してから、StimulusのJavaScriptコード内でDOMの<meta>要素にクエリをかけて値を取り出せます。

使い方

まず、アプリケーションテンプレートで<head>セクションの内側に<meta>タグを追加します。ここでは例として、アプリをtestモードで実行するときに設定を変えたいのでRails.envの値を知りたいとします(私も最近、サードパーティのライブラリの設定をヘッドレスシステムテストで動くよう変更しなければならなかったことがありました)。

Railsのtagヘルパーを使えば、文字列の式展開を大量に書かずに済みます。

<!-- アプリケーションレイアウトの<head>タグの内側に以下を書く -->

<%= tag :meta, name: :rails_env, content: Rails.env %>

上のコードから以下のように<meta>タグが生成されます。

<meta name="rails_env" content="development">

次に、Stimulusのコントローラでこのタグにクエリをかけて中身を読み出します。

import { Controller } from '@hotwired/stimulus'

export default class extends Controller {
  connect() {
    if (this.isTestEnvironment) {
      // test環境で何かする
    } else {
      // developmentやproduction環境で何かする
    }
  }

  get isTestEnvironment() {
    return document.head.querySelector("meta[name=rails_env]").content === "test"
  }
}

必要なら、これをヘルパーに切り出すことも可能です。以下はRailsのrequest.jsライブラリにあるユーティリティ関数ですが、ここでも同じ<meta>タグのパターンを用いて、JavaScriptリクエストを送信するときにRailsのCSRFトークンにアクセスしています。

function metaContent (name) {
  const element = document.head.querySelector(`meta[name="${name}"]`)
  return element && element.content
}

ただし、このデータはページのHTMLソースコードに露出することをくれぐれも忘れてはいけません。サーバー上にしか存在しない環境変数と異なり、データをHTMLに置くとエンドユーザーに読まれてしまいます。くれぐれも、一般に公開しても安全なデータだけを公開するようにしてください。

参考資料

関連記事

Rails: Action Viewのdom_idヘルパーは実は有能(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。