Eloguent のマスアサインメント機能を使って、テーブルにデータを追加してみます。
下記の create() メソッドに配列で値を渡すことで、1文でテーブルにデータを追加することができます。
App\Article::create(['title' => '3件目の記事', 'body' => '吾輩は猫である', 'published_at' => Carbon\Carbon::now()]);
では、tinker を使って実際にやってみます。
php artisan tinker >>> App\Article::create(['title' => '3件目の記事', 'body' => '吾輩は猫である', 'published_at' => Carbon\Carbon::now()]); Illuminate\Database\Eloquent\MassAssignmentException with message 'title'
何やら、MassAssignmentException という例外エラーが発生しました。
実はEloquentのマスアサインメントでは事前に登録できる項目を宣言しておく必要があります。下記のようにモデルの fillable 変数に配列で宣言します。
<?php // app/Article.php namespace App; use Illuminate\Database\Eloquent\Model; class Article extends Model { protected $fillable = ['title', 'body', 'published_at']; }
もう一度、tinker でやってみます。
tinker は再起動してください。
php artisan tinker >>> App\Article::create(['title' => '3件目の記事', 'body' => '吾輩は猫である', 'published_at' => Carbon\Carbon::now()]); => { title: "3件目の記事", body: "吾輩は猫である", published_at: { date: "2015-06-18 08:14:06.000000", timezone_type: 3, timezone: "UTC" }, updated_at: "2015-06-18 08:14:06", created_at: "2015-06-18 08:14:06", id: 2 } >>> App\Article::all()->toArray(); => [ [ "id" => "1", "title" => "はじめてのタイトル", "body" => "かくかくしかじか", "created_at" => "2015-02-22 21:08:16", "updated_at" => "2015-02-22 21:08:16", "published_at" => "2015-02-22 20:47:07" ], [ "id" => "2", "title" => "3件目の記事", "body" => "吾輩は猫である", "created_at" => "2015-02-23 16:32:31", "updated_at" => "2015-02-23 16:32:31", "published_at" => "2015-02-23 16:32:31" ] ]
今度は上手く行きました!
マスアサインメントのセキュリティー対策
では何故、マスアサインメントでは、このように fillable を使って、ガードする必要があるのでしょうか?
マスアサインメントは、ユーザからのリクエストをテーブルに保存する処理で使用されます。リクエストに想定していな項目が含まれていた場合、そのまま更新されてしまうと、重大なセキュリティーホールとなってしまうためです。
例えばUserクラスに name, age, admin の3カラムがあり、adminはユーザーの画面からは更新させない管理者権限だとします。Userの新規登録処理で、以下のようなコードを書いていた場合…
$article = AppUser::create($request->all());
不正リクエストなどによって $request に admin が含まれていた場合、管理者権限を任意の値に設定されてしまいます。
その為、マスアサインメントでは fillableで宣言した項目のみに許可を与え、それ以外をガードしているのです。
https://laravel.com/docs/5.6/eloquent#mass-assignment
広告