【问题标题】:Why my data is not storing in database using eloquent?为什么我的数据没有使用 eloquent 存储在数据库中?
【发布时间】:2020-09-10 22:07:33
【问题描述】:

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

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

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

Controller 上的功能存储:

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>

【问题讨论】:

  • 请将代码作为文本(带有适当的标记)添加到您的问题中,而不是作为图像。
  • @NigelRen 完成,抱歉
  • dd($user) 在 $user->save() 之前查看 $user 是否按预期获取属性。
  • 试试 $user->forget('password_confirmation');保存前。
  • 如果有错误信息,请通过编辑添加到问题中

标签: php html laravel eloquent laravel-7


【解决方案1】:

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

'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 调用未定义的方法 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 类使散列变得简单。

$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'
];

然后在你的控制器中,你就可以放心使用了

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 2019-11-06
    • 2017-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多