Skip to content

Scaffoldは一体何をしているのか?生成されるコードを1行ずつ解説

はじめに

Railsのscaffoldは、開発の初期段階で非常に便利なコマンドです。モデル、ビュー、コントローラなど、Webアプリケーションの基本的な構成要素を自動で生成してくれます。しかし、その便利さゆえに「中で何が起きているかよくわからないまま使っている」という方も多いのではないでしょうか。

この記事では、rails generate scaffoldコマンドが生成するファイルを1つずつ丁寧に読み解き、Railsアプリケーションの仕組みへの理解を深めることを目的とします。

前提

以下のコマンドが実行済みであるとします。

bash
rails generate scaffold Article title:string content:text

1. config/routes.rb - ルーティング

scaffoldを実行すると、まずconfig/routes.rbに以下の1行が追加(またはアンコメント)されます。

ruby
# config/routes.rb
Rails.application.routes.draw do
  resources :articles
end
  • resources :articles: これは、articlesリソースに対する一連のRESTfulなルートを自動で定義するための記述です。具体的には、以下の7つのアクションに対応するURLとコントローラのアクションがマッピングされます。
HTTPメソッドURLパスコントローラ#アクション用途
GET/articlesarticles#index全記事の一覧表示
GET/articles/newarticles#new新規記事の作成フォーム
POST/articlesarticles#create新規記事の作成処理
GET/articles/:idarticles#show特定記事の詳細表示
GET/articles/:id/editarticles#edit特定記事の編集フォーム
PATCH/PUT/articles/:idarticles#update特定記事の更新処理
DELETE/articles/:idarticles#destroy特定記事の削除処理

この1行だけで、ブログ記事の基本的な操作に必要なすべてのURLが定義されます。

2. app/controllers/articles_controller.rb - コントローラ

次に、リクエストを処理するコントローラを見てみましょう。

ruby
# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  before_action :set_article, only: %i[ show edit update destroy ]

  # GET /articles
  def index
    @articles = Article.all
  end

  # GET /articles/1
  def show
  end

  # GET /articles/new
  def new
    @article = Article.new
  end

  # GET /articles/1/edit
  def edit
  end

  # POST /articles
  def create
    @article = Article.new(article_params)

    if @article.save
      redirect_to @article, notice: "Article was successfully created."
    else
      render :new, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /articles/1
  def update
    if @article.update(article_params)
      redirect_to @article, notice: "Article was successfully updated."
    else
      render :edit, status: :unprocessable_entity
    end
  end

  # DELETE /articles/1
  def destroy
    @article.destroy
    redirect_to articles_url, notice: "Article was successfully destroyed."
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_article
      @article = Article.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def article_params
      params.require(:article).permit(:title, :content)
    end
end
  • before_action :set_article, ...: show, edit, update, destroyアクションが実行される前に、set_articleメソッドを呼び出す設定です。これにより、各アクションで@article = Article.find(params[:id])という記述を繰り返す必要がなくなります。
  • index: Article.allですべての記事を取得し、インスタンス変数@articlesに格納します。この変数はビュー(index.html.erb)で使われます。
  • show: before_action@articleがセットされるので、中身は空です。
  • new: 新しいArticleオブジェクトを作成し、@articleに格納します。これはビューのフォーム (form_with) で使われます。
  • edit: before_action@articleがセットされるので、中身は空です。
  • create: newアクションから送信されたパラメータ(article_paramsで安全にフィルタリング済み)を使って新しい記事を作成し、データベースに保存します。保存が成功すれば記事詳細ページにリダイレクトし、失敗すればnewのビューを再表示します。
  • update: editアクションから送信されたパラメータで記事を更新します。成功すれば記事詳細ページにリダイレクトし、失敗すればeditのビューを再表示します。
  • destroy: 記事を削除し、記事一覧ページにリダイレクトします。
  • privateメソッド:
    • set_article: URLの:idパラメータを使って、対象の記事をデータベースから見つけます。
    • article_params: Strong Parametersという仕組みです。フォームから送られてきたデータのうち、titlecontentだけを許可し、意図しないデータが登録されるのを防ぎます。

3. app/models/article.rb - モデル

モデルファイルは非常にシンプルです。

ruby
# app/models/article.rb
class Article < ApplicationRecord
end
  • class Article < ApplicationRecord: ArticleクラスがApplicationRecordを継承することを示しています。ApplicationRecordActiveRecord::Baseを継承しており、これによりArticleモデルはデータベースのarticlesテーブルと連携し、find, all, save, update, destroyなどのメソッドが使えるようになります。

4. app/views/articles/ - ビュー

scaffoldは、各アクションに対応するビューファイルも生成します。

  • index.html.erb: 記事一覧ページ。@articlesをループして各記事のタイトルを表示し、詳細ページへのリンクを設置します。
  • show.html.erb: 記事詳細ページ。@articleのタイトルと内容を表示します。
  • new.html.erb: 新規作成ページ。_form.html.erbパーシャルを呼び出します。
  • edit.html.erb: 編集ページ。こちらも_form.html.erbパーシャルを呼び出します。
  • _form.html.erb: neweditで共有されるフォーム部分のテンプレート(パーシャル)です。form_with(model: article) を使い、@articleが新規オブジェクトか既存オブジェクトかを自動で判断して、適切なPOST先(createupdate)にフォームを送信します。

5. db/migrate/xxxxxxxx_create_articles.rb - マイグレーション

最後に、データベースのテーブル定義です。

ruby
# db/migrate/20240628000000_create_articles.rb (タイムスタンプは実行日時による)
class CreateArticles < ActiveRecord::Migration[7.0]
  def change
    create_table :articles do |t|
      t.string :title
      t.text :content

      t.timestamps
    end
  end
end
  • create_table :articles: articlesという名前のテーブルを作成します。
  • t.string :title: titleという名前のstring型(文字列)カラムを追加します。
  • t.text :content: contentという名前のtext型(長文テキスト)カラムを追加します。
  • t.timestamps: created_atupdated_atという2つのタイムスタンプカラムを自動で追加します。これにより、データの作成日時と更新日時が記録されます。

このファイルをもとにrails db:migrateを実行することで、実際にデータベースにテーブルが作成されます。

まとめ

scaffoldは、これらすべてのファイルを連携させて、一つのまとまった機能を一瞬で作り上げてくれます。それぞれのファイルがどのような役割を持ち、どのように連携しているかを理解することで、scaffoldを単なる「魔法のコマンド」から、カスタマイズ可能な「開発の土台」として活用できるようになります。

ぜひ、生成されたコードを自分なりに改造して、Railsアプリケーションの仕組みをより深く探求してみてください。

AI が自動生成した技術記事をまとめたテックブログ