0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React Admin × Rails APIで作る管理画面

Posted at

はじめに

この記事では、React Admin と Rails API を使って、シンプルな管理画面を構築する方法を紹介します。最終的には投稿(Post)とユーザー(User)を管理できる画面を作ります。

前半はほぼ公式チュートリアルに従って行い、後半は Rails API を使って自分の作ったデータへ干渉できるようにします。

最終的な完成イメージは次の通りです。

admin.gif

※ 本記事では「React Admin を使った管理画面の構築」にフォーカスして進めていきます。
Ruby on Rails 環境(Ruby や Bundler、Rails 本体など)のセットアップについては省略していますので、必要に応じてあらかじめご準備いただければと思います。

React Admin 環境構築

まずは、React Admin の開発環境をセットアップしていきます。以下のコマンドをターミナルで実行してください。

$ npm init react-admin test-admin
$ cd test-admin
$ npm install ra-data-json-server
$ npm run dev

http://localhost:5173 にアクセスして次のような画面になったら正しく動いています。

スクリーンショット 2025-04-12 14.07.20.png

次にデータ取得や更新のために dataProvider を設定する必要があります。dataProvider.tsを作成してsrc/に追加します。

src/dataProvider.ts
import jsonServerProvider from 'ra-data-json-server';

const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com');

export default dataProvider;

この jsonServerProvider は、React Admin が用意している公式の REST API クライアントで、指定した URL に対して GET、POST、PUT などのリクエストを自動的に発行してくれます。

ここでは、モックデータ API として有名な JSONPlaceholder を使用しています。

このサービスでは、投稿データ(/posts)やユーザー情報(/users)など、管理画面に必要なサンプルデータが RESTful API 形式で提供されています。

試しに、https://jsonplaceholder.typicode.com/posts にアクセスすると次のようなデータが得られると思います。

[
  {
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  },
  {
    "userId": 1,
    "id": 2,
    "title": "qui est esse",
    "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
  },
  
  ...

  {
    "userId": 10,
    "id": 99,
    "title": "temporibus sit alias delectus eligendi possimus magni",
    "body": "quo deleniti praesentium dicta non quod\naut est molestias\nmolestias et officia quis nihil\nitaque dolorem quia"
  },
  {
    "userId": 10,
    "id": 100,
    "title": "at nam consequatur ea labore ea harum",
    "body": "cupiditate quo est a modi nesciunt soluta\nipsa voluptas error itaque dicta in\nautem qui minus magnam et distinctio eum\naccusamus ratione error aut"
  }
]

このデータを次のステップで綺麗に表示していきます。

投稿管理画面の作成

一覧画面の作成

まずは投稿(Post)の一覧を表示するために、次のようにフォルダ/ファイルを追加します。

src/pages フォルダ、そしてその下に posts フォルダを作成し、そこに PostList.tsx を追加します。
React Admin の List コンポーネントと Datagrid を使って、投稿の ID、タイトル、本文、ユーザーを一覧表示できるようにします。

src/pages/posts/PostList.tsx
import { List, Datagrid, TextField, ReferenceField, EditButton } from "react-admin";

const PostList = () => (
    <List>
        <Datagrid>
            <TextField source="id" />
            <TextField source="title" />
            <TextField source="body" />
            <ReferenceField source="userId" reference="users" />
            <EditButton />
        </Datagrid>
    </List>
);

export default PostList;

次に、App.tsx を編集してこの画面をルーティングに追加します。

src/App.tsx
import { Admin, Resource } from "react-admin";
import dataProvider from './dataProvider';

import PostList from './pages/posts/PostList';

export const App = () => (
    <Admin dataProvider={dataProvider}>
        <Resource name="posts"
            list={PostList}
        />
    </Admin>
);

ここまで実装すると、投稿の一覧が表形式で表示されるようになります。

スクリーンショット 2025-04-12 14.11.39.png

詳細・編集・新規作成ページの追加

同様に次のファイルも作成して、詳細ページ、編集ページ、新規作成ページも作ります。

src/pages/posts/PostShow.tsx
import { Show, SimpleShowLayout, TextField, ReferenceField } from "react-admin";

const PostShow = () => (
    <Show>
        <SimpleShowLayout>
            <TextField source="id" />
            <TextField source="title" />
            <TextField source="body" />
            <ReferenceField source="userId" reference="users" />
        </SimpleShowLayout>
    </Show>
);

export default PostShow;
src/pages/posts/PostEdit.tsx
import { Edit, SimpleForm, TextInput, ReferenceInput } from "react-admin";

const PostEdit = () => (
    <Edit>
        <SimpleForm>
            <TextInput source="title" />
            <TextInput source="body" />
            <ReferenceInput source="userId" reference="users" />
        </SimpleForm>
    </Edit>
);

export default PostEdit;
src/pages/posts/PostCreate.tsx
import { Create, SimpleForm, TextInput, ReferenceInput } from "react-admin";

const PostCreate = () => (
    <Create>
        <SimpleForm>
            <TextInput source="title" />
            <TextInput source="body" multiline rows={5} />
            <ReferenceInput source="userId" reference="users" />
        </SimpleForm>
    </Create>
);

export default PostCreate;

App.tsx に詳細・編集・作成ページを追加してルーティングを有効にします。

App.tsx
import { Admin, Resource } from "react-admin";
import dataProvider from './dataProvider';

import PostList from './pages/posts/PostList';
+ import PostShow from './pages/posts/PostShow';
+ import PostEdit from './pages/posts/PostEdit';
+ import PostCreate from './pages/posts/PostCreate';

export const App = () => (
    <Admin dataProvider={dataProvider}>
        <Resource name="posts"
            list={PostList}
+           show={PostShow}
+           edit={PostEdit}
+           create={PostCreate}
        />
    </Admin>
);

スクリーンショット 2025-04-12 14.14.01.png

スクリーンショット 2025-04-12 14.14.37.png

スクリーンショット 2025-04-12 14.15.09.png

ここまでの実装が完了すると、一覧から投稿の詳細を確認したり、編集画面・作成画面へ遷移できるようになります。

なお、今は外部のモック API(JSONPlaceholder)を使用しているため、編集や新規作成を行っても実際にはサーバー側に保存されません。そのため、扱えるのは一覧と詳細のみとなります。

Rails API の設定

このステップでは、React Admin のフロントエンドと連携するための Rails API サーバーを構築していきます。まずはデータベース設計として Post モデルと User モデルを用意し、それらのリレーション設定、初期データの投入までを行います。

モデル作成

まずは、投稿情報を管理する Post モデルと、それに紐づくユーザー情報を管理する User モデルを作成します。

$ rails g model Post
$ rails g model User

それぞれのマイグレーションファイルを編集して、必要なカラムを追加します。

db/migrate/2025xxxxxxxxxx_create_posts.rb
class CreatePosts < ActiveRecord::Migration[7.1]
    def change
        create_table :posts do |t|
+           t.string :title
+           t.text :body
+           t.integer :user_id
            t.timestamps
        end
    end
end
db/migrate/2025xxxxxxxxxx_create_users.rb
class CreateUsers < ActiveRecord::Migration[7.1]
    def change
        create_table :users do |t|
+           t.string :name
+           t.string :email
            t.timestamps
        end
    end
end

カラムの追加が完了したら、マイグレーションを実行してテーブルを作成します。

$ rails db:migrate

加えて、User は複数の Post を持つ(1:N)、という関係性をモデルに定義します。
これで、ユーザーと投稿がリレーションで繋がり、Rails 側での関連付けができるようになります。

app/models/post.rb
class Post < ApplicationRecord
    belongs_to :user
end
app/models/user.rb
class User < ApplicationRecord
    has_many :posts, dependent: :destroy
end

また、今回は一覧画面を作るので初期データをあらかじめ作っておきます。

db/seeds.rb
User.create!(name: "Alice", email: "alice@example.com")
User.create!(name: "Bob", email: "bob@example.com")
User.create!(name: "Charlie", email: "charlie@example.com")

User.all.each do |user|
    4.times do |n|
        user.posts.create!(
            title: "テストタイトル#{n + 1}",
            body: "テスト本文#{n + 1}"
        )
    end
end
$ rails db:seed

これで初期データの投入が完了しました。

この段階で、React Admin から扱うための基本的なデータ構造が整いました。次はこれらのデータを外部へ公開するために、API エンドポイントの実装に進んでいきます。

コントローラー作成

ここからは、React Admin 側と通信するための Rails 側の API コントローラーを作成していきます。
前ステップで作成したモデルに対して、一覧取得・詳細取得・作成・更新・削除といった典型的な REST 操作を提供するエンドポイントを整備します。

$ rails g controller api/v1/posts
$ rails g controller api/v1/users

このコマンドで、それぞれのエンドポイントに対応するコントローラーファイルとルーティングが生成されます。

続いて、Api::V1::PostsController に RESTful なアクションを実装していきます。

app/controllers/api/v1/posts_controller.rb
class Api::V1::PostsController < ApplicationController
    def index
        start_params = params[:_start].present? ? params[:_start].to_i : 0
        end_params = params[:_end].present? ? params[:_end].to_i : 10
        limit = end_params - start_params
        posts = Post.offset(start_params).limit(limit)
        response.set_header('X-Total-Count', Post.all.count)
        render json: posts
    end

    def show
        post = Post.find(params[:id])
        render json: post
    end

    def create
        post_new = Post.new(post_params)
        if post_new.save
            render json: post_new
        else
            render json: { status: 'error', errors: post_new.errors.full_messages }
        end
    end
    
    def update
        post = Post.find(params[:id])
        if post.update(post_params)
            render json: post
        else
            render json: { status: 'error', errors: post.errors.full_messages }
        end
    end

    def destroy
        post = Post.find(params[:id])
        post.destroy
        render json: post
    end
    
    private
    def post_params
        params.require(:post).permit(:title, :body, :user_id)
    end
end

同様に、ユーザー一覧などを取得できる Api::V1::UsersController を実装します。

app/controllers/api/v1/users_controller.rb
class Api::V1::UsersController < ApplicationController
    def index
        start_params = params[:_start].present? ? params[:_start].to_i : 0
        end_params = params[:_end].present? ? params[:_end].to_i : 10
        limit = end_params - start_params
        users = User.offset(start_params).limit(limit)
        response.set_header('X-Total-Count', User.all.count)
        render json: users
    end

    def show
        user = User.find(params[:id])
        render json: user
    end

    def create
        user_new = User.new(user_params)
        if user_new.save
            render json: user_new
        else
            render json: { status: 'error', errors: user_new.errors.full_messages }
        end
    end

    def update
        user = User.find(params[:id])
        if user.update(user_params)
            render json: user
        else
            render json: { status: 'error', errors: user.errors.full_messages }
        end
    end

    def destroy
        user = User.find(params[:id])
        user.destroy
        render json: user
    end

    private
    def user_params
        params.require(:user).permit(:name, :email)
    end
end

最後に、ルーティングファイルを編集して API を有効にします。

config/routes.rb
Rails.application.routes.draw do
    namespace :api do
        namespace :v1 do
            resources :posts, except: %i[new edit]
            resources :users, except: %i[new edit]
        end
    end
end

これで、React Admin 側から http://localhost:3000/api/v1/postshttp://localhost:3000/api/v1/users に対してリクエストを送ることで、Rails 側のデータと連携できるようになりました。

その他設定

フロントエンドと Rails API を連携させる際、サーバー側の設定もいくつか必要になります。そのままでは CSRF や CORS の制約に引っかかってしまうため、以下のように設定を加えていきます。

まずは Rails を API 専用モードに設定します。これにより、不要なビューやアセット、CSRF 保護などが無効化され、API サーバーとしてシンプルになります。

config/application.rb
module App
    class Application < Rails::Application
        ...
        config.api_only = true
    end
end

次に、CORS(オリジン間リソース共有)を許可する設定を行います。Rails では rack-cors というミドルウェアを使うのが一般的です。

config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
    allow do
        origins "http://localhost:5173" # React Admin の開発サーバーURL

        resource "*",
            headers: :any,
            expose: ['X-Total-Count'],
            methods: [:get, :post, :put, :patch, :delete, :options, :head]
    end
end

もし config/initializers/cors.rb が存在しない場合は、Gemfile に以下を追記してから bundle install を実行してください。

Gemfile
+ gem "rack-cors"
$ bundle install

これでフロントエンドと接続する準備が完了しました。

次のステップでは、React Admin 側の dataProvider をローカルの Rails API に切り替え、実際に CRUD 処理を動かしてみます。

投稿管理画面の修正

ここからは、フロントエンド(React Admin)を Rails のローカル API サーバーに接続するように切り替えていきます。

前ステップまでは https://jsonplaceholder.typicode.com を使っていましたが、ここからは自分で立てた Rails API を使って、投稿やユーザーの追加・削除などができるようになります。

src/dataProvider.ts
import jsonServerProvider from 'ra-data-json-server';

const dataProvider = jsonServerProvider('http://localhost:3000/api/v1');
 
export default dataProvider;

また、Rails のデフォルトでは外部キー名はスネークケース(user_id)となっているため、React Admin 側のフィールド指定もそれに合わせる必要があります。

src/pages/posts/PostList.tsx
import { List, Datagrid, TextField, ReferenceField, EditButton } from "react-admin";

const PostList = () => (
    <List>
        <Datagrid>
            <TextField source="id" />
            <TextField source="title" />
            <TextField source="body" />
+           <ReferenceField source="user_id" reference="users" />
            <EditButton />
        </Datagrid>
    </List>
);
export default PostList;

この修正は一覧表示に限らず、詳細表示(PostShow.tsx)、編集(PostEdit.tsx)、新規作成(PostCreate.tsx)など、該当フィールドを使用している全ての画面に適用してください。

スクリーンショット 2025-04-12 16.37.15.png

rails db:seed で投入したテストデータが、上のように一覧画面で表示されていれば成功です。

ユーザー管理画面の作成

加えて User の管理画面も作ってみましょう。

src/pages/UserList.tsx
import { List, Datagrid, TextField, EditButton } from "react-admin";

const UserList = () => (
    <List>
        <Datagrid>
            <TextField source="id" />
            <TextField source="name" />
            <TextField source="email" />
            <EditButton />
        </Datagrid>
    </List>
);
export default UserList;
src/pages/UserShow.tsx
import { Show, SimpleShowLayout, TextField } from "react-admin";

const UserShow = () => (
    <Show>
        <SimpleShowLayout>
            <TextField source="id" />
            <TextField source="name" />
            <TextField source="email" />
        </SimpleShowLayout>
    </Show>
);

export default UserShow;
src/pages/UserEdit.tsx
import { Edit, SimpleForm, TextInput } from "react-admin";

const UserEdit = () => (
    <Edit>
        <SimpleForm>
            <TextInput source="name" />
            <TextInput source="email" />
        </SimpleForm>
    </Edit>
);

export default UserEdit;
src/pages/UserCreate.tsx
import { Create, SimpleForm, TextInput } from "react-admin";

const UserCreate = () => (
    <Create>
        <SimpleForm>
            <TextInput source="name" />
            <TextInput source="email" />
        </SimpleForm>
    </Create>
);

export default UserCreate;

最後に、App.tsx にユーザーリソースを追加して表示されるようにします。

App.tsx
import { Admin, Resource } from "react-admin";
import dataProvider from './dataProvider';

import PostList from './pages/posts/PostList';
import PostShow from './pages/posts/PostShow';
import PostEdit from './pages/posts/PostEdit';
import PostCreate from './pages/posts/PostCreate';

+ import UserList from './pages/users/UserList';
+ import UserShow from './pages/users/UserShow';
+ import UserEdit from './pages/users/UserEdit';
+ import UserCreate from './pages/users/UserCreate';

export const App = () => (
    <Admin dataProvider={dataProvider}>
        <Resource name="posts"
            list={PostList}
            show={PostShow}
            edit={PostEdit}
            create={PostCreate}
        />
+       <Resource name="users"
+           list={UserList}
+           show={UserShow}
+           edit={UserEdit}
+           create={UserCreate}
+       />
    </Admin>
);

表示を確認して、ユーザー一覧や詳細、編集・作成ページが問題なく表示されていれば完了です。

スクリーンショット 2025-04-12 16.42.04.png

スクリーンショット 2025-04-12 16.42.19.png

スクリーンショット 2025-04-12 16.42.30.png

スクリーンショット 2025-04-12 16.42.46.png

これで、投稿とユーザーの CRUD 管理ができるシンプルな管理画面がひと通り完成しました。

おわりに

今回は React Admin と Rails API による実用的な管理画面作成を行いました。

  • 外部サービス(jsonplaceholder)からスタート

  • ローカル API に切り替え

  • 投稿とユーザーの一覧 / 詳細 / 編集 / 作成まで対応

という一連の流れを通して、React Admin の基本的な使い方と、Rails API の連携方法が理解できたと思います。

ぜひ自分のプロジェクトにも活用してみてください!

参考サイト

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?