LaravelでコントローラーにDBデータの取得の処理とか書いているんだけど、コントローラーの記述量が増えてみにくい。同じような記述も目立つし、別のファイルにロジックをまとめられないかなぁ…
こんな疑問を解決します。
コントローラーにもDBからデータを取得するロジックだったり、テーブルにデータを登録する処理を書いていませんか?
その場合は、コントローラーの記述量も増えてファットコントローラーの原因になります。
ファットコントローラーとは、文字どおり太ったコントローラーをさし、記述量が多くてみづらいコードになってしまうんですね。
この記事では、DBのロジックはモデルに切り分けることでファットコントローラを回避する方法を解説していきます。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
動作確認した環境
Docker 20.10.7
PHP 7.4.22
Laravel 8.53.1
mySQL 5.7
データベースのツール phpmyadmin
ファットコントローラーの状態
ファットコントローラーの状態だと、コントローラーの記述量が多くなってコントローラーのコードを追うのが大変になります。
冒頭でも書いたように、この記事ではデータベースから取得する操作はコントローラーではなく全てモデルに記述することでファットコントローラーを回避しましょうという内容です。
【ファットコントローラーの状態】
public function index()
{
$company = new Company();
// companiesテーブルからデータを全て取得
$getAllCompanies = $company->all();
}
public function store(Request $request)
{
$company = new Company();
// フォームから入力された会社名を取得
$companyName = $request->company_name;
// フォームから入力された会社パスワードを取得
$password = $request->password;
// companiesテーブルにデータを登録処理
$insertCompany = $company->create([
'company_name' => $companyName,
'password' => Hash::make($password),
]);
}
上記の場合、ファットコントローラーになるので、
- new Company();を一つにまとめる
- データの取得や登録のメソッドはコントローラーではなくモデルに書いて関数を呼び出す
上記のようにします。
public function __construct()
{
$this->company = new Company();
}
public function index()
{
// companiesテーブルからデータを全て取得
$company = $this->company->findAllCompany();
}
public function store(Request $request)
{
// フォームから入力された会社名を取得
$companyName = $request->company_name;
// フォームから入力された会社パスワードを取得
$password = $request->password;
// companiesテーブルにデータを登録処理
$company = $this->company->insertCompany($companyName, $password);
}
完成形としては以下になります。
かなりスッキリとしてますね。
実務では、登録や更新処理を記述するときに、データベースの取得もかなり複雑になるのでモデルに書く方法をここで身につけましょう!
モデルにDBロジックを切り分ける手順
constructにnew Company()をかく
まずは、indexとstoreで毎回new Company()と書いている部分を一つにまとめます。
<?php
namespace App\Http\Controllers;
use App\Models\Company;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class CompanyController extends Controller
{
private $company;
public function __construct()
{
$this->company = new Company();
}
public function index()
{
}
public function create(Request $request)
{
}
public function store(Request $request)
{
}
}
上記のようにprivate $company;とプロパティを定義します。
そして__constructの中に、new Company()を定義します。
ここではわかりやすいように’$this->company = new Company();’と定義しました。
construct内に記述することで、自動的にインスタンスを生成してくれます。
モデルに関数を書く
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Hash;
class Company extends Model
{
use HasFactory;
// モデルに関連付けるテーブル
protected $table = 'companies';
// テーブルに関連付ける主キー
protected $primaryKey = 'company_id';
// 登録・更新可能なカラムの指定
protected $fillable = [
'company_name',
'password',
'created_at',
'updated_at'
];
/**
* companiesテーブルのデータを全件取得
*
* @return コレクション配列
*/
public function findAllCompany()
{
return $this->all();
}
/**
* companiesテーブルにデータを登録する
*
* @param string $companyName 会社名
* @param string $password パスワード
* @return コレクション配列
*/
public function insertCompany($companyName, $password)
{
return $this->create([
'company_name' => $companyName,
'password' => Hash::make($password),
]);
}
}
上記のようにモデル内にデータベースのロジックの関数を定義します。
※モデル内の書き方はLaravel公式ドキュメントをご参照ください。
$thisはモデルのクラスを指します。
コントローラーでいう$company = new Company();で定義した$companyになります。
なので、$this->all()は、
$company = new Company();
$company->all();
と同じ意味です。
モデル内に関数がかけたので、あとはコントローラーで関数を呼び出しましょう。
コントローラーで関数を呼び出す
<?php
namespace App\Http\Controllers;
use App\Models\Company;
use App\Models\CompanyPassword;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class CompanyController extends Controller
{
private $company;
public function __construct()
{
$this->company = new Company();
}
public function index()
{
// companiesテーブルからデータを全て取得
$company = $this->company->findAllCompany();
}
public function create(Request $request)
{
}
public function store(Request $request)
{
// フォームから入力された会社名を取得
$companyName = $request->company_name;
// フォームから入力された会社パスワードを取得
$password = $request->password;
// companiesテーブルにデータを登録処理
$company = $this->company->insertCompany($companyName, $password);
}
}
上記のように、モデルで定義した関数は’$this->company->関数名’と繋げればOKです。
【まとめ】モデルにDBロジックを書いてファットコントローラーを回避
今回は、モデルにデータベースのロジックを書くことで、ファットコントローラーを回避する方法を解説しました。
Laravel初心者のかたで個人アプリを作成している方は、コントローラーにベタ書きではなく、今回の方法を試してみてステップアップしてみましょう!
このブログでは実務で役立つLaravelの記事を他にも書いているので、合わせてチェックよろしくお願いします!
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
コメント