ララベルのマニュアルで紹介されている一般的な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'];メルマガ購読の申し込みはこちらから。