今回この記事を書こうと思ったきっかけ
今通っているスクールで過去の生徒のコードレビュー動画を見ていた時に、レビューをしていたエンジニアの人がコントローラーはテストしずらいのでコントローラーにはあまりロジックを書かずに、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モデルでスコープを定義することで絞り込みの処理をモデルに移すことができます
このように、コントローラとモデルを組み合わせることで、コードの再利用性と保守性が向上します。モデルにビジネスロジックやデータのバリデーション、スコープの定義をすることで、コントローラはよりシンプルでリクエストの処理に集中できます。