概要
- マスアサインメントによって、フォームから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'])); |