Controllerファイルの機能について

## この記事で何がわかるか？
①Controllerファイルで、なぜリクエスト処理やモデルオブジェクトの操作が出来るか？
②継承元のControllerは、どんな役割があるか？


## モデル名の付いたコントローラーから分かること

```HomeController.rb
class HomeController < ApplicationController
  def top
  end
  
  def about
  end
end
```

```PostsController.rb
class PostsController < ApplicationController
  def index
    @posts = Post.all.order(created_at: :desc)
  end
  
  def show
    @post = Post.find_by(id: params[:id])
  end
  
  def new
    @post = Post.new
  end
  
  def create
    @post = Post.new(content: params[:content])
    if @post.save
      flash[:notice] = "投稿を作成しました"
      redirect_to("/posts/index")
    else
      render("new")
    end
  end
  
  def edit
    @post = Post.find_by(id: params[:id])
  end
  
  def update
    @post = Post.find_by(id: params[:id])
    @post.content = params[:content]
    if @post.save
      flash[:notice] = "投稿を編集しました"
      redirect_to("/posts/index")
    else
      render("edit")
    end
  end
  
  def destroy
    @post = Post.find_by(id: params[:id])
    @post.destroy
    flash[:notice] = "投稿を削除しました"
    redirect_to("/posts/index")
  end
end
```

モデル名の付いたControllerから分かるのは、
①ApplicationControllerを継承している
②アクションメソッド内で、モデルオブジェクトの操作やリクエスト・リダイレクト処理を行なっている

**モデル名の付いたコントローラーでは、対象モデルに関する操作などを行っているんですね。**
では継承元のActionControllerはどうでしょうか？


## アプリケーションのコントローラーから分かること

```ApplicationController.rb
class ApplicationController < ActionController::Base
  def confirm_login
    if session[:user_id] == nil
      flash[:notice] = 'ログインが必要です'
      redirect_to("/login")
    else
      @current_user = User.find(session[:user_id])
    end
  end
  
  def after_login
    if session[:user_id]
      flash[:notice] = 'すでにログインしています'
      redirect_to("/posts/index")
    end
  end
  
  def identify_user
    if @current_user.id != params[:id].to_i
      flash[:notice] = '権限がありません'
      redirect_to("/posts/index")
    end
  end
end
```
アプリケーションのコントローラーから分かるのは、
①ActionControllerを継承している
②リクエスト・リダイレクト処理やモデルオブジェクトの操作を行なっている点は、モデルのコントローラーと同じ
③ログイン認証など、継承先のコントローラーで共有する機能がある

```UserController.rb
class UsersController < ApplicationController
  before_action :confirm_login, only: [:index, :show, :edit, :update] ## ApplicationControllerのメソッドを呼び出し
  
  def index
    @users = User.all
  end
  
  def show
    @user = User.find_by(id: params[:id])
  end
  
  def edit
    @user = User.find_by(id: params[:id])
  end
  
  def update
    @user = User.find_by(id: params[:id])
    @user.name = params[:name]
    @user.email = params[:email]
    if params[:image_name]
      @user.image_name = "#{@user.id}.jpg"
      File.binwrite("public/user_images/#{@user.image_name}", params[:image_name].read)
    end
    if @user.save
      flash[:notice] = "ユーザー情報を編集しました"
      redirect_to("/users/#{@user.id}")
    else
      render("users/edit")
    end
  end
end
```

アプリケーションのコントローラーでは、モデル名の付いたコントローラーで共有する機能を実装するんだと思います。
「ActionController::Base」では、どんな機能があるのでしょうか？


## 「ActionController::Base」から分かること

Railsアプリの前フォルダを調べてみましたが、「ActionController.rb」は無かったです。実は外部にある「ActionControllerのbase.rb」を、railsアプリ作成時に自動的に読み込み、パラメータ処理やセッション管理などを可能にしているんですね。

「ActionControllerのbase.rb」の内容
https://github.com/rails/rails/blob/main/actionpack/lib/action_controller/base.rb

「ActionControllerのbase.rb」のおかげで、モデル名の付いたコントローラー内でモデルオブジェクトの操作やリクエスト・リダイレクト処理が出来るんですね。


## コントローラーの継承関係を図にするとこうなる
![スクリーンショット 2023-11-24 22.15.20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3568357/c37816f9-f4da-7f22-c274-e8197cd3b93a.jpeg)


## 調べてみて分かったこと
①ApplicationControllerでは、各モデルのコントローラーで共有する機能を実装する
②「ActionControllerのbase.rb」に、ViewとModelの連携でよく使う機能が用意されているから、継承先のコントローラーでその機能を活用できる