概要
- マスアサインメントによって、フォームからPOSTされたパラメーターを一括してモデルの属性にセットして、データベースに書き込める
- ただしセットできる属性をモデルの
$fillable配列に限定列挙する必要がある - モデルのインスタンス生成時に、セットできるパラメーターをonlyメソッドで限定列挙できる
$fillableのほかに$guarded配列も指定できて、こちらは指定した属性をモデルのセットの際に排除する
準備
以下のようなフォームがあって、nameとcommentをPOSTする。
|
1 2 3 4 5 6 |
<form method="post"> @csrf <div><label>名前: <input type="text" name="name"></label></div> <div><label>コメント: <input type="text" name = "comment"></label></div> <input type="submit" value="投稿"> </form> |
POSTはコントローラーのstore()メソッドにルーティングされる。
|
1 |
Route::post('/messages', 'MessageController@store'); |
ルーティング先のコントローラーでは、モデルのインスタンスを生成し、その属性にPOSTされたパラメーターをセットしてデータベースに書き込む。
|
1 2 3 4 5 6 7 8 9 10 11 |
class MessageController extends Controller { ..... public function store(Request $request) { $message = new Message(); $messsage->name = $request->name; $messsage->comment = $request->comment; $message->save(); ..... } } |
マスアサインメント
Requestのall()メソッド
Request引数のall()メソッドで得られる内容を確認。
|
1 2 3 4 5 6 7 8 |
class MessageController extends Controller { ..... public function store(Request $request) { dd($request->all()); ..... } } |
CSRF対策のトークンを含んだパラメーターの配列が得られる。
|
1 2 3 4 5 |
array:3 [▼ "_token" => "DPci3aVibUshjdv5xGhllPZHvGgfdIUNh5iMniO9" "name" => "test" "comment" => "test comment" ] |
$request->all()の結果を、モデルインスタンスのfill()メソッドによって属性にセット。dd()で内容を確認してみる。
|
1 2 3 4 5 6 7 8 9 10 |
class MessageController extends Controller { ..... public function store(Request $request) { $message = new Message(); $message->fill($request->all()); dd($message); ..... } } |
エラー。
マスアサインメントのためにはfillable属性に加えなければならないと言われる。
|
1 2 |
Illuminate\Database\Eloquent\MassAssignmentException Add [_token] to fillable property to allow mass assignment on [App\Message]. |
モデルの$fillableプロパティー
モデルの定義で、$fillable配列に取得したいプロパティーを列挙する。
|
1 2 3 4 |
class Message extends Model { protected $fillable = ['name', 'comment']; } |
先ほどのコードの実行結果。エラーがなくなる。dd()でプロパティーがセットされたインスタンスの内容を確認。
fillableプロパティーに2つのパラメーター名がセットされているattributesに属性とその内容が配列としてセットされているguardedは指定しておらず、サイズ1、内容'*'の配列となっている
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
App\Message {#323 ▼ +fillable: array:2 [▼ 0 => "name" 1 => "comment" ] ..... #attributes: array:2 [▼ "name" => "test" "comment" => "test comment" ] ..... #guarded: array:1 [▼ 0 => "*" ] } |
以上を踏まえて、fillableがセットされたモデルのマスアサインメントとデータベース登録を以下に例示。
|
1 2 3 4 5 6 7 8 9 10 |
class MessageController extends Controller { ..... public function store(Request $request) { $message = new Message(); $message->fill($request->all()); $message->save(); ..... } } |
マスアサインメントの記述方法
マスアサインメントの書き方には複数あって、同じ結果が得られる。create()スタティックメソッドは、インスタンスの生成とデータベースの書き込みを一つのメソッドで行う。
|
1 2 3 4 5 6 7 8 |
$message = new Message(); $message->fill($request->all()); $message->save(); または $message = new Message($request->all()); $message->save(); または $message = Message::create($request->all()); |
Requestのonly()メソッドによる限定
意図しないパラメーターの追加を避けるため、all()メソッドではなくonly()メソッドでパラメーターを限定列挙できる。
|
1 |
$message = Message::create($request->only(['name', 'comment'])); |