LoginSignup
0
1

controllerにはあまりロジックを書かないほうがいいらしい

Last updated at Posted at 2023-09-11

今回この記事を書こうと思ったきっかけ

今通っているスクールで過去の生徒のコードレビュー動画を見ていた時に、レビューをしていたエンジニアの人がコントローラーはテストしずらいのでコントローラーにはあまりロジックを書かずに、Modelに逃がすか、違う層(helperなど)に書いた方がいいとアドバイスしていたのでそこが気になったので今回は理解を深めるために、コントローラの単体実装とコントローラとモデルの組み合わせ実装の2つのコード例を書いてみた。

コントローラの単体実装

class AnimalsController < ApplicationController
  def index
    animals = Animal.where(trading_status:0)

    if params[:pet_type].present?
      animals = animals.where(pet_type: params[:pet_type])
    end

    if params[:vaccinated].present?
      animals = animals.where(vaccinated: params[:vaccinated])
    end

    if params[:spayed_neutered].present?
      animals = animals.where(spayed_neutered:params[:spayed_neutered])
    end

    if params[:sex].present?
      animals = animals.where(sex: params[:sex])
    end

    if params[:age].present?
      animals = animals.where(age: params[:age])
    end

    if params[:prefecture].present?
      animals = animals.where(prefecture: params[:prefecture])
    end

    @animals = animals.shuffle
  end

end

上記の例は、単体のコントローラの実装です。trading_statusが0の全ての動物の情報を取得して
そこからさらにプルダウンで選択できるようにしております

コントローラとモデルの組み合わせ実装

controllerは以下の通り

class AnimalsController < ApplicationController
  def index
    animals = Animal.animals

    if params[:pet_type].present?
      animals = animals.pet_type(params[:pet_type])
    end

    if params[:vaccinated].present?
      animals = animals.vaccinated(params[:vaccinated])
    end

    if params[:spayed_neutered].present?
      animals = animals.spayed_neutered(params[:spayed_neutered])
    end

    if params[:sex].present?
      animals = animals.sex(params[:sex])
    end

    if params[:age].present?
      animals = animals.age(params[:age])
    end

    if params[:prefecture].present?
      animals = animals.prefecture(params[:prefecture])
    end

    @animals = animals.shuffle
  end
end

modelは以下の通り

class Animal < ApplicationRecord
  scope :animals, -> {
    where(trading_status: 0)
  }

  scope :pet_type, -> (pet_type){
    where(pet_type: pet_type) 
  }

  scope :vaccinated, -> (vaccinated) {
    where(vaccinated: vaccinated) 
  } 

  scope :spayed_neutered, -> (spayed_neutered) {  
    where(spayed_neutered: spayed_neutered)
  }

  scope :sex, -> (sex) {
    where(sex: sex)
  }

  scope :age, -> (age) {
    where(age: age)
  }

  scope :prefecture, -> (prefecture) {
    where(prefecture: prefecture)
  }
end

上記の例では、コントローラとモデルの組み合わせ実装を示しています。Animalモデルでスコープを定義することで絞り込みの処理をモデルに移すことができます

このように、コントローラとモデルを組み合わせることで、コードの再利用性と保守性が向上します。モデルにビジネスロジックやデータのバリデーション、スコープの定義をすることで、コントローラはよりシンプルでリクエストの処理に集中できます。

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