ララベルのマニュアルで紹介されている一般的なDBレコードの作成方法は、
class Member extends Model
{
protected $table = 'member';
protected $primary_key = 'member_id';
protected $timestamps = true;
}
use App\Models\Member;
$member = new Member();
$member->name = '山田太郎';
$member->email = 'tyamada@gmail.com';
$member->password = 'password'; // ここもちろん実際は暗号化して
$member->save();
Memberのインスタンスを作成し、ちまちまとそれぞれの項目を埋めて、最後にセーブ。
しかし、ウェブのアプリでは、コントローラーにおいて、ユーザーの入力がたくさんの項目でいっぺんに入ってくるので、
namespace App\Http\Controllers;
use App\Models\Member;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class SignupController extends Controller
{
public function postSignup(Request $request)
{
$member = new Member;
$member->fill($request->all())->save();
}
}
と、先のようにひとつひとつの項目に値を割り当てずに、一気に保存することできます。いわゆる、一括割り当てのマスアサインメント(Mass Assignment)です。
しかし、このコード、ちょっと問題があります。
上のコードでは、フォームからポストされる項目名がすべてが、クラスMemberのDBテーブルにあると仮定して、ララベルは一括割り当てを試みます。
たとえば、以下のようなフォームでは、
<form method="post" action="signup">
ログイン:
<input type="email" name="email" value="{{ old('email') }}" required autofocus>
パスワード:
<input type="password" name="password" required>
パスワードの確認:
<input type="password" name="password_confirmation" required>
名前:
<input type="text" name="name" value="{{ old('name') }}" required>
<button type="submit">保存</button>
</form>
以下の項目が入力項目名ですが、
email
password
password_confirmation
name
password_confirmationは、通常、パスワード確認のための入力項目でDBには存在しない項目です。その値をDBに入れようとするところでエラーとなります。
どうしましょう?
エロクエント(Eloquent)では、どの値をDBに入れてよいか、どれを入れていけないかのルールの設定が可能です。$fillableあるいは$guardedのどちらかの変数の定義がその目的で使用されます。前者は、ホワイトリスト(入力OKの項目のリスト)、後者はブラックリスト(入力禁止の項目のリスト)です。
class Product extends Model
{
protected $table = 'member';
protected $primary_key = 'member_id';
protected $timestamps = true;
protected $fillable = ['email', 'password', 'name'];
}
こうすれば、エラーがなくDBに値を無事に入れることができます。
$fillableの代わりに、以下でも良いですね。
protected $guarded = ['password_confirmation'];メルマガ購読の申し込みはこちらから。
