为什么我的数据没有使用 eloquent 存储在数据库中?

Why my data is not storing in database using eloquent?

我的表单已提交,但未存储在 table 中。如果我对请求执行 dd(),数据就在其中,但是当我执行 save() 时,它不会按预期工作。我想在后台表单上添加用户,只需使用姓名、电子邮件、用户类型和密码。

编辑:我将问题图片更改为代码,以便对您来说更容易,对于第一次尝试,我们深表歉意。 编辑 2:现在出现了更多 2 件事,password_confirmation 上的验证总是错误的,如果我跳过验证会给我这个错误:

BadMethodCallException 调用未定义的方法 App\User::forget()

控制器上的功能存储:

public function store(Request $request)
    {
        $dados = $request->validate(
            [
                'name'  =>'required|min:2|max:20',
                'email' =>'required|email|unique:App\User,email',
                'password' =>'required|min:8',
                'password_confirmation' =>'confirmed'
            ],
            [
                'required' =>'Os campos têm de ser todos preenchidos!',
                'email' =>'O email tem de ser válido!',
                'unique'=>'O email inserido já está registado!',
                'min.name' =>'O nome tem de ter pelo menos 2 caracteres!',
                'min.password' =>'A password tem de ter no minimo 8 caracteres!',
                'confirmed' =>'As passwords deverão coincidir!'
            ]
        );

        $user = new User;
        $user->forget('password_confirmation');
        $user->fill($request->all());
        $user->save();

        return redirect()->route('utilizadores.index')->with('Success','Utilizador registado com sucesso!');
    }

路线:

Route::resource('/admin/utilizadores', 'UserController');

型号:

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $guarded = [

    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token','password_confirmation'
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

表格:

<div class="modal-body">
            <form action="{{route('utilizadores.store')}}" method="POST" id="adicionarid">
                @csrf
                <input type="email" name="email" class="inputtext data" placeholder="Email">
                <div class="customselect data top1">
                    <select name="tipo">
                        <option value="revisor" selected disabled>Revisor</option>
                        <option value="editor">Editor</option>
                        <option value="revisor">Revisor</option>
                    </select>
                </div>
                <input type="text" name="name" class="inputtext" placeholder="Nome">
                <input type="password" name="password" class="inputtext" placeholder="Palavra-passe">
                <input type="password" name="password_confirmation" class="inputtext" placeholder="Confirmar palavra-passe">
            </form>
        </div>
        <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">Fechar</button>
            <button type="submit" class="btn btn-success" form="adicionarid">Guardar</button>
        </div>

我在您的代码中发现了很多问题。让我们先把它们列出来,这样你就知道你做错了什么

'password_confirmation' =>'confirmed'

我很确定这不会按照您的预期进行。 confirmed 验证规则必须在 password 上使用,laravel 将自动检查是否存在名为 password_confirmation (field_name_confirmation) 的字段并检查它是否存在等于 password 字段。所以你的验证规则可以是

'password' =>'required|min:8|confirmed',

并且不需要关于 password_confirmation

的规则

接下来是

$user->forget('password_confirmation');

eloquent 或 laravel 的查询生成器中没有 forget 方法,因此你得到

BadMethodCallException Call to undefined method App\User::forget()

CollectionsArr::forget() 上有 forget 方法,但这不是您想要的。但是由于您已经有了 $dados,它将是一个仅包含您在验证器中为其定义规则的输入字段的数组,因此您可以在创建用户时使用 $dados(稍后将在答案)

接下来是

$user->fill($request->all());

永远不要这样做,因为恶意用户可以在表单中添加额外的字段,例如 id,从而允许他们修改现有用户。

相反你可以做

$user->fill($dados);

由于$dados只包含验证器返回的字段,使用起来更安全。

我注意到的另一个问题是您在表单中有一个名为 tipo 的字段,但它不存在于验证器中,因此您需要将其添加到验证器中。

$dados = $request->validate(
    [
        'name'  =>'required|min:2|max:20',
        'email' =>'required|email|unique:App\User,email',
        'password' =>'required|min:8|confirmed',
        'tipo' =>'required' // Add whatever other validations you need
    ],
    [
        'required' =>'Os campos têm de ser todos preenchidos!',
        'email' =>'O email tem de ser válido!',
        'unique'=>'O email inserido já está registado!',
        'min.name' =>'O nome tem de ter pelo menos 2 caracteres!',
        'min.password' =>'A password tem de ter no minimo 8 caracteres!',
        'confirmed' =>'As passwords deverão coincidir!'
    ]
);

那你就可以了

$user = new User;
$user->fill($dados);
$user->save();

下一个问题是您没有散列密码。除非你想直接将用户密码保存在数据库中,否则你应该散列密码; Laravel 通过提供您可以使用的 Hash class 使散列变得简单。

$dados['password'] = Hash::make($request->password);

请务必在文件顶部添加 use Illuminate\Support\Facades\Hash;

总的来说,通过一些调整你的控制器应该

public function store(Request $request)
{
    $dados = $request->validate(
        [
            'name'  =>'required|min:2|max:20',
            'email' =>'required|email|unique:App\User,email',
            'password' =>'required|min:8|confirmed',
            'tipo' =>'required' // Add whatever other validations you need
        ],
        [
            'required' =>'Os campos têm de ser todos preenchidos!',
            'email' =>'O email tem de ser válido!',
            'unique'=>'O email inserido já está registado!',
            'name.min' =>'O nome tem de ter pelo menos 2 caracteres!',
            'password.min' =>'A password tem de ter no minimo 8 caracteres!',
        ]
    );

    $dados['password'] = Hash::make($request->password);

    $user = new User;
    $user->fill($dados);
    $user->save();

    return redirect()->route('utilizadores.index')->with('Success','Utilizador registado com sucesso!');
}

它应该可以实现您希望实现的目标

现在,让我们给你一些额外的提示。

始终避免使用空 $guarded

protected $guarded = [

];

它可能会留下安全漏洞(即使您没有暴露任何此类漏洞,粗心的其他人也可能会,因此请始终尝试使用 $fillable,安全总比抱歉好)

protected $fillable = [
    'name', 'email', 'password', 'tipo'
];

那么在你的controller中,你可以放心的使用

$user = User::create($dados);

这是一种比fill()更广泛使用的方法。 $fillable 数组还确保在使用 create() 时,只有 $fillable 数组中的属性才会保存在数据库