Chapter 16

[Laravel]Create model methods for business logic,Create Action classes

at yasu
at yasu
2022.02.28に更新
このチャプターの目次

コントローラーに記述するコード量は少ないのに越したことはありません。しかし、例えば、注文に応じて請求用のデータを挿入する処理が必要になり、コントローラーに書いてしまうことは避けたいです。

そういうときは注文モデル(Order)にメソッドを追加して処理を書いてしまうことです。

参考 :

✗ bad


// OrderController::postOrder

DB::transaction(function()use($order){
	$invoice = $order->invoice()->create();
	$order->pushStatus(new AwaitingShipping());
	return $invoice;
});

○ Good


// OrderController::postOrder
$order->createInvoice();

// Order::createInvoice
if($this->invoice()->exists()){
	throw new OrderAlreadyHasAnInvoice('Order already has an Invoice');
}

$self = $this;
return DB::transaction(function()use($self){
	$invoice = $self->invoice()->create();
	$self->pushStatus(new AwaitingShipping());
	return $invoice;
});


◎ best

細かいビジネスロジックな処理は、後から要望が増えていきます。そして色んな所から呼び出されたりしますので、そういうのだけ分ける事をします。

// Order
public function createInvoice(): Invoice
{
	if($this->invoice()->exists()){
		throw new OrderAlreadyHasAnInvoice('Order already has an Invoice');
	}
	return app(\App\Action\CreateInvoiceForOrder::class)($this);
}


// App\Action\CreateInvoiceForOrder
class CreateInvoiceForOrder
{

	public function __invoke(Order $order): Invoice
	{
		return DB::transaction(function()use($order){
			$invoice = $order->invoice()->create();
			$order->pushStatus(new AwaitingShipping());
			return $invoice;
		});
	}
}