spree-admin について
spree-adminは、Spree 5.xのRailsベースの旧管理画面をカスタマイズする開発者向けスキルです。リソースのスキャフォールド生成に加え、ナビゲーション、テーブル、ビュー、コントローラーの変更を扱います。
主な機能
- 01CRUD管理画面のスキャフォールド生成
- 02サイドバーナビゲーションのカスタマイズ
- 03テーブル列の設定
- 04ビューのオーバーライドとパーシャルの挿入
- 05管理画面用フォームヘルパーの利用
活用シーン
- 01モデル用の管理画面追加
- 02管理一覧とナビゲーションの調整
- 03カスタムビューによる管理画面の拡張
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ spree/ agent-skills --skill spree-adminインストール後、Claude Code で/spree-adminを入力して読み込まれたか確認します。
詳細
Spree Legacy Rails Admin (spree_admin)
以下のコマンドでは Spree CLI 形式(
spree …、Docker)を使用します。CLI を使わない従来の Rails アプリ(通常は 5.4 より前)では、spree-projectスキルのネイティブな対応方法を使用してください。アプリのルートからbin/rails/bundle exec rakeを実行し、パスからbackend/プレフィックスを除きます。
管理画面は Rails エンジンです。ERB ビューをサーバー側でレンダリングし、インタラクティブ機能には Stimulus + Turbo、スタイルには Tailwind を使用します。(Spree 6.0 では新しい React ベースの管理画面が導入されます。Spree 5.x では spree_admin が管理画面です。)
プロジェクト構成
Rails 管理画面は spree_admin gem にあり、/admin にマウントされています。通常の Rails アプリとして扱ってください。
spree_admin gem
├── app/
│ ├── controllers/spree/admin/ # admin controllers
│ ├── views/spree/admin/<resource>/ # ERB views per resource
│ ├── helpers/spree/admin/ # view helpers
│ ├── presenters/spree/admin/ # presenter pattern for complex views
│ ├── javascript/spree/admin/ # Stimulus controllers, importmap-managed
│ └── models/spree/admin/navigation* # nav + nav builder
└── lib/generators/spree/admin/
├── install/ # bin/rails g spree:admin:install
└── scaffold/ # bin/rails g spree:admin:scaffold
ホストアプリ(backend/)では、同じパスにあるファイルを backend/app/ の下でオーバーライドしてカスタマイズします。Rails のビューのパス解決では、gem よりもホストアプリのファイルが優先されます。
新しい管理リソースの追加(1 コマンドで実行)
Spree には、任意のモデルの CRUD 管理画面一式を生成する管理画面スキャフォールドジェネレーターが用意されています。モデルとマイグレーションを作成した後(spree:api_resource または spree:model を使用します)に、次を実行します。
spree rails g spree:admin:scaffold Spree::Brand
次のファイルが生成されます。
| ファイル | 用途 |
|---|---|
backend/app/controllers/spree/admin/brands_controller.rb | Spree::Admin::ResourceController を継承するコントローラー |
backend/app/views/spree/admin/brands/index.html.erb | 一覧ページ(render_table @collection, :brands をレンダリングします。列はテーブルレジストリから取得します) |
backend/app/views/spree/admin/brands/new.html.erb | 作成フォームページ |
backend/app/views/spree/admin/brands/edit.html.erb | 編集フォームページ |
backend/app/views/spree/admin/brands/_form.html.erb | 共通フォームのパーシャル |
backend/config/initializers/spree_admin_brands_table.rb | テーブル列の登録 |
backend/config/initializers/spree_admin_brands_navigation.rb | サイドバーナビゲーションの登録 |
backend/config/routes.rb | add_routes ブロックに挿入される namespace :admin { resources :brands } |
ジェネレーターは、Spree::Core::Engine.add_routes do ブロック(spree-starter テンプレートに含まれています)の内側に、backend/config/routes.rb へのルートも挿入します。routes.rb にこのブロックがない場合は、手動でルートを追加してください。
# backend/config/routes.rb
Rails.application.routes.draw do
Spree::Core::Engine.add_routes do
namespace :admin do
resources :brands
end
end
mount Spree::Core::Engine, at: '/'
end
add_routes(生の Spree::Core::Engine.routes.append ではありません)がサポート対象の方法です。アプリの再読み込み時にルートが二重に定義されるのを防ぎます。
(API に spree:api_resource を使用する場合、API のルートは管理画面のルートとは別です。異なる名前空間にあります。)
新しいイニシャライザーとルートを読み込むため、Rails を再起動してください。
spree restart
サイドバーのカスタマイズ
サイドバーの項目はイニシャライザーで登録します。基本パターンは次のとおりです。
# backend/config/initializers/spree_admin_brands_navigation.rb
Rails.application.config.after_initialize do
Spree.admin.navigation.sidebar.add :brands,
label: :brands, # i18n key or string
url: :admin_brands_path, # symbol → route helper, or string
icon: 'list', # Tabler icon name (https://tabler.io/icons)
position: 55, # lower = earlier in sidebar
active: -> { controller_name == 'brands' }, # when to highlight
if: -> { can?(:manage, Spree::Brand) } # CanCanCan visibility check
end
よく使われるナビゲーションのパターン:
# Top-level item that opens a sub-menu
Spree.admin.navigation.sidebar.add :marketing, label: :marketing, position: 30 do |nav|
nav.add :promotions, label: :promotions, url: :admin_promotions_path, position: 10
nav.add :coupon_codes, label: :coupon_codes, url: :admin_coupon_codes_path, position: 20
end
# Remove an existing entry
Spree.admin.navigation.sidebar.remove :reports
# Reorder an existing entry
Spree.admin.navigation.sidebar.update :products, position: 5
必要に応じて、ナビゲーション API の全容は spree/admin/app/models/spree/admin/navigation.rb でソースを確認できます。
管理画面のテーブルのカスタマイズ
管理画面の一覧ページの大半(Products、Orders、Promotions など)では、登録済みのテーブル定義を使用します。登録済みのキーは gem の config/initializers/spree_admin_tables.rb を参照してください(注:Customers ページは :users として登録されています。Payment Methods など、一部のページではテーブルレジストリを使用しません)。イニシャライザーから列を追加、削除、または並べ替えます。
# backend/config/initializers/spree_admin_products_table_customization.rb
Rails.application.config.after_initialize do
# Add a column to the existing Products table
Spree.admin.tables.products.add :brand_name,
label: :brand, # i18n key
type: :string, # :string | :number | :date | :datetime | :money | :status | :link | :boolean | :image | :custom | :association
sortable: true,
filterable: true,
default: true, # visible by default (vs opt-in via column toggle)
position: 25
# Remove a column
Spree.admin.tables.products.remove :sku
# Update an existing column
Spree.admin.tables.products.update :name, label: :product_name
end
独自に生成したテーブル(spree:admin:scaffold を使用)では、適切なデフォルト設定(name、created_at、updated_at)を含むイニシャライザーが生成されます。ドメイン固有の列を追加してください。
カスタム列のレンダリング:列の値が直接の属性ではない場合は、モデルまたはプレゼンター/デコレーターにメソッドを定義します。列のキー(add の最初の引数)は、デフォルトで検索メソッドとして使用されます。method: を渡すと、別のメソッド名やレコードを受け取るラムダを指定できます。たとえば、Products テーブルに brand_name 列を追加する場合は、Product モデルまたはプレゼンターに brand_name を定義します。
# In your model or decorator
def brand_name
brand&.name
end
ビューの上書き
同じパスのファイルをホストアプリに置くと、Rails はそのファイルを使用します。gem には spree/admin/app/views/spree/admin/products/index.html.erb が含まれており、backend/app/views/spree/admin/products/index.html.erb に置くと上書きできます。
注意点が 2 つあります。
-
まずファイル全体をコピーしてから編集してください。一部だけの上書きは機能しません。Rails はホストアプリのファイルをそのまま使用します。
bundle show spree_adminを使うと、gem 内のビューの場所を確認できます。 -
ビューのファイルには、インタラクティブな動作のための
data-controllerStimulus バインディングがあります。data-controller="…"属性を削除すると、関連する JS が動作しなくなります。明示的に置き換えるのでない限り、バインディングは残してください。
軽微な上書きには、ビュー全体を上書きする代わりに、管理画面の名前付きインジェクションポイントを使用してください。ビューは render_admin_partials を使って、登録された部分テンプレートのリスト(例:head、body_end、products_header、product_form)をレンダリングします。部分テンプレート(例:backend/app/views/spree/admin/shared/_my_banner.html.erb)を作成し、イニシャライザーに登録します。
Rails.application.config.after_initialize do
Spree.admin.partials.body_end << 'spree/admin/shared/my_banner'
end
コンソールで Spree.admin.partials.keys を実行すると、すべてのインジェクションポイントを一覧表示できます。
管理画面 UI の構築 — フォームビルダー、コンポーネント、ヘルパー
管理画面のビューや部分テンプレート(スキャフォールドで生成したリソースフォーム、挿入した product_form セクション、上書きしたビュー)を書くときは、生の Rails ヘルパーではなく、管理画面独自の UI 用語を使ってください。一貫したスタイル、ラベル、エラー表示、i18n をすぐに利用できます。
フォームビルダー(重要)
管理画面のすべての form_with は、自動的に Spree::Admin::FormBuilder(管理画面の BaseController にある default_form_builder)を使用します。設定は不要です。
<%= form_with model: [:admin, @brand] do |f| %>
<%= f.spree_text_field :name, required: true %>
<%= f.spree_text_field :code, help: "Leave blank to auto-generate" %>
<%= f.spree_money_field :price, currency: current_store.default_currency %>
<%= f.spree_collection_select :tax_category_id, Spree::TaxCategory.all, :id, :name,
{ include_blank: true, autocomplete: true }, {} %>
<%= f.spree_check_box :active %>
<%= f.spree_file_field :logo, width: 240, height: 240 %>
<% end %>
メソッドの全一覧:spree_text_field、spree_number_field、spree_money_field(ロケールに対応した区切り文字を使用し、送信時に小数値へ正規化して、通貨記号を追加します)、spree_email_field、spree_date_field、spree_datetime_field、spree_text_area(自動で高さを調整します)、spree_rich_text_area(Trix)、spree_select / spree_collection_select(検索可能なドロップダウンにするには autocomplete: true を渡します。選択肢が 20 個以上あるセレクトで使用してください)、spree_check_box、spree_radio_button(特定のラジオボタンにラベルを紐付けるには、明示的な :id を渡してください。指定しない場合、ラベルは値で照合されます)、spree_file_field(ドラッグ&ドロップ、プレビュー、crop: true、allowed_file_types:)。
すべてのメソッドで共通のオプション:label:(文字列、または非表示にする場合は false)、required:(アスタリスクを表示)、help:(フィールドの下に表示するテキスト)、help_bubble:(ラベルの横に表示するツールチップアイコン)、class:。バリデーションエラーはフィールドの下に自動で表示されます。ラベルは i18n(spree.<attribute>、次に activerecord.attributes.spree/<model>.<attribute>)を使って解決されます。
UI コンポーネント
ヘルパーでレンダリングする、管理画面のデザインシステムに合ったコンポーネントです。独自にマークアップを作成する代わりに、これらを使用してください。
| コンポーネント | ヘルパー |
|---|---|
| ドロップダウン | dropdown { dropdown_toggle + dropdown_menu } |
| ダイアログ(モーダル)/ドロワー(サイドパネル) | dialog_header、dialog_close_button、dialog_discard_button;drawer_header、drawer_close_button |
| アイコン | icon('plus') — Tabler のアイコン名 |
| フォールバック付き画像 | spree_image_tag |
| ツールチップ | tooltip、help_bubble |
| ステータスバッジ | active_badge(condition) |
| アバター、クリップボードへのコピー、プログレスバー | render_avatar、clipboard_component / clipboard_button、progress_bar_component |
| ストアのタイムゾーンでの日付 | spree_date、spree_time、spree_time_ago、local_time |
知っておくと便利なビュー ヘルパー
- ナビゲーション/リンク:
link_to_with_icon、link_to_edit、link_to_delete(Turbo の確認機能を内蔵)、button、external_link_to、page_header_back_button - Turbo:
turbo_save_button_tag(保存中の状態を表示して送信)、turbo_render_alerts、turbo_close_dialog - コンテキスト:
current_store、current_currency、try_spree_current_user、supported_currencies - モデルの設定:
preference_fields/preference_field_for— モデルのpreference :x宣言に対応するフォーム入力欄を自動的に描画します(決済方法とストアの設定フォームはこの方法で構築されています)
完全なリファレンスは、ローカルドキュメントの node_modules/@spree/docs/dist/developer/admin/form-builder.md、components.md、helper-methods.md にあります。
管理画面のコントローラーをデコレートする
Spree の管理画面コントローラーは通常の Rails コントローラーなので、ほかのコントローラーと同様にデコレートできます。spree generate controller_decorator Spree::Admin::ProductsController でファイルを生成すると、prepended フックと prepend の配線を含む backend/app/controllers/spree/admin/products_controller_decorator.rb が生成されます(ジェネレーターはモジュールをネストし、完全修飾の prepend 行を外側に配置します。手書きで同等のものを作成する場合は、こちらのほうが簡潔です)。
# backend/app/controllers/spree/admin/products_controller_decorator.rb
module Spree::Admin::ProductsControllerDecorator
def self.prepended(base)
base.before_action :my_custom_check, only: [:create, :update]
end
private
def my_custom_check
# ...
end
end
Spree::Admin::ProductsController.prepend Spree::Admin::ProductsControllerDecorator
これはナビゲーションやテーブルのカスタマイズよりも影響が大きいため、アクションの動作を変更する必要がある場合に限って使用してください。まず、サブスクライバー(副作用向け)やサービスの差し替え(ビジネスロジック向け)で対応できないか確認してください。カスタマイズの判断基準の全体については、spree-project スキルを参照してください。
Stimulus コントローラー — 管理画面のインタラクティブ機能
Rails 管理画面では、クライアント側のインタラクティブ機能に Stimulus と Turbo を使用しています。既存のコントローラーは spree_admin/app/javascript/spree/admin/controllers/ にあります。
| コントローラー | 機能 |
|---|---|
sidebar_controller.js | サイドバーの切り替えと状態の保持 |
variants_form_controller.js | 商品編集時のバリアント管理 |
page_builder_controller.js | CMS ページビルダーのドラッグ&ドロップ |
bulk_editor_controller.js | 複数行のテーブル編集 |
dropdown_controller.js | ドロップダウンメニュー |
独自の Stimulus コントローラーを追加するには、backend/app/javascript/controllers/ に配置し、importmap(backend/config/importmap.rb)で登録します。ビューからは data-controller="my-controller" で参照します。
Turbo Streams(サーバーからプッシュされる UI の更新)では、Rails 7 以降の Hotwire アプリと同じパターンを使用できます。コントローラーから turbo_stream.* を描画し、ID を使ってフレームを指定します。
判断基準:どのような管理画面の変更ですか?
| 目的 | 使用するもの |
|---|---|
| 独自ページへのリンクをサイドバーに追加する | イニシャライザーで Spree.admin.navigation.sidebar.add |
| 管理画面のテーブルに列を追加する | イニシャライザーで Spree.admin.tables.<name>.add |
| 新しいリソースの CRUD セクションを追加する | bin/rails g spree:admin:scaffold Spree::YourModel |
| フォームを作成または編集する | f.spree_* フォームビルダーのメソッド。「管理画面の UI を構築する」を参照してください |
| モーダル/ドロップダウン/バッジ/ツールチップを追加する | コンポーネント ヘルパー。「管理画面の UI を構築する」を参照してください |
| 既存ページの見た目を変更する | backend/app/views/spree/admin/... のビューをオーバーライドする |
| コントローラーに新しいアクションを追加する | デコレーター(最後の手段です。まず spree-project スキルを参照してください) |
| フォームの入力欄をインタラクティブにする | Stimulus コントローラーと、ビュー内の data-controller="..." |
| UI にリアルタイム更新をプッシュする | サブスクライバーまたはサービスから Turbo Stream ブロードキャストを送信する |
| 管理画面全体のスタイルを変更する | backend/app/assets/tailwind/spree_admin.css(インストーラーによって作成されます)を編集します。このファイルは gem の基本スタイルを app/assets/tailwind/spree/admin/index.css からインポートします。ここに @theme のオーバーライドとカスタム Tailwind を追加します |
さらに詳しく知りたい場合
- 管理画面のソース:
bundle show spree_adminで、インストールされた gem のパスを確認できます。gem のルートにある README では、基本理念について説明しています。 - カスタマイズのドキュメント:
node_modules/@spree/docs/dist/developer/admin/では、各種パターンを説明しています。 - ナビゲーション API:
Spree::Admin::Navigationのソースには、ナビゲーションをカスタマイズするためのメソッドがすべて記載されています。 - テーブル API: gem 内の
Spree::Admin::Table(app/models/spree/admin/table.rb)およびSpree::Admin::Table::Column(app/models/spree/admin/table/column.rb)には、列の種類、オプション、並べ替え・フィルタリングの詳細が記載されています。Spree.admin.tablesの背後にあるレジストリは、lib/spree/admin/engine.rb内のSpree::Admin::Engine::TablesEnvironmentです。 - スキャフォールドジェネレーター:
bundle show spree_admin/lib/generators/spree/admin/scaffold/ に、より高度なカスタマイズに使えるテンプレートファイルがあります。 - フォームビルダー/コンポーネント/ヘルパー:
node_modules/@spree/docs/dist/developer/admin/form-builder.md、components.md、helper-methods.mdには、上記の「管理画面 UI の構築」で扱うすべての項目について、オプションの一覧表が記載されています。