3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Linkbal(リンクバル)Advent Calendar 2023

Day 12

【Rails】Active Adminの管理画面にVueを導入する方法

Posted at

本記事では、管理画面のUI/UX向上を目的として、RailsのActive AdminにVueを導入する方法について紹介します。

注意事項

Rails、およびVueプロジェクト立ち上げ方については本記事では触れません。また、今回はVueのビルドツールとしてViteを採用しています。Webpackでは動作しませんので、ご了承ください。

本題

管理画面にVueを適用するためには、最低限HTMLファイル上で以下2つの設定する必要があります。

  • VueをマウントするためのHTML要素の用意
  • バンドルされたJSファイルとCSSファイルのインポート

しかし、Active AdminはDSL(ドメイン固有言語)であり、通常直接HTMLファイルを編集することはありません。Rubyのコードを基にHTMLが自動生成されます。

ですが、抜け道としてカスタムページという機能が用意されており、任意のhtmlファイルを表示させることが出来るので、これを使用します。

sample.rb
ActiveAdmin.register_page 'Sample' do
  content do
    # ここで読み込みたいhtmlファイルを指定する。
    # ファイル名の先頭はアンダーバーにする必要あり。(_index.html)
    render partial: 'admin/sample/index'
  end
end

↑で登録したhtmlファイルに対して、先ほど述べた2つの設定を記述してきましょう。

_index.html.erb
<div class="panel" id="app"> // VueをマウントするためのHTML要素
</div>

<%= csrf_meta_tag %> // CSRFを防ぐための呪文

<% if Rails.env.development? %>
  <script type="module" src="http://localhost:3030/src/main.ts"></script>
<% else %>
  <% hash = File.open("#{Rails.root.to_s}/public/api/sample/manifest.json") { |f| JSON.load(f) } %>
  <script type="module" src="/api/sample/<%= hash["src/main.ts"]["file"] %>"></script>
  <script>
    const link = document.createElement('link')
    link.rel  = 'stylesheet'
    link.href = "/api/sample/<%= hash['src/main.css']['file'] %>"
    document.getElementsByTagName('head')[0].appendChild(link)
  </script>
<% end %>

ここでポイントとなるのは、JSファイルの読み込み方法です。開発環境と本番環境で方法が異なります。

開発環境の場合、Viteを実行すると、現在の作業ディレクトリをルートとしたサーバが起動します。ので、例えばルートディレクトリにpackage.jsonがあるならば、ブラウザURLにhttp://localhost:8080/package.jsonと入力すれば、画面にはその中身が表示されるかと思います。

ここではVueのエントリーファイル、即ちVueアプリの作成&マウント処理を行っているJSファイルをインポートします。特別なカスタマイズをしていなければ、src/main.tsが、それに該当するはずです。

main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index.js'

const app = createApp(App) // Vueアプリの作成
app.use(router)
app.mount('#app') // アプリのマウント

一方、本番環境ではリソースのバンドルが行われるので、ファイル名および出力先が開発環境と異なります。また、本番環境ではビルド毎にファイル名にハッシュ値が付与されるため、ファイルパスをハードコーディングすることが出来ません。

そこで、ビルド毎に生成されたファイル名を取得したいというユースケースに応えるため、Viteではビルド時にmanifest.jsonというファイルを一緒に生成してくれます。Rails側からこのファイルの中身を読み込みましょう。

manifest.json
{
  "src/main.css": {
    "file": "assets/main-f957ddef.css",
    "src": "src/main.css"
  },
  "src/main.ts": {
    "css": [
      "assets/main-f957ddef.css"
    ],
    "file": "assets/app-19789f2f.js",
    "isEntry": true,
    "src": "src/main.ts"
  }
}

ちなみにビルドの出力先ですが、今回はpublicディレクトリを使用しています。publicディレクトリはRailsの静的ファイルを格納する場所で、これらのファイルはアプリケーションのルートURLから直接アクセスできます。

publicディレクトリにバンドルファイルを出力するよう、Vite側の設定も変更しておきましょう。これはvite.confing.tsのoutDirで指定できます。

vite.config.ts
export default defineConfig({
  plugins: [vue()],
  build: {
    manifest: true, // manifest.jsonの生成を有効にする
    outDir: '../public/api/sample',
  }
}

設定は以上になります。localhost:3000の該当ページにアクセスして、Viteの初期ページが表示されるか確認してみてください。

参考

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?