如何验证记录更新中的唯一字段
Posted
技术标签:
【中文标题】如何验证记录更新中的唯一字段【英文标题】:How to validate a unique field on a record update 【发布时间】:2021-01-16 10:41:33 【问题描述】:我最近启动了一个 laravel 项目来控制一些活动,但我目前在更新包含唯一值的表上的特定记录时遇到了验证问题
在上个月 laravel 8 发布的几天内,有一些笔记开始了这个项目,所以也许有一些变化影响了我。
这些是我的迁移
第一个是用户及其数据, ...
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB; //para hacer insersion
class CrearTablaUsuarios extends Migration
/**
* Run the migrations.
*
* @return void
*/
public function up()
Schema::create('usuarios', function (Blueprint $table)
$table->increments('id_usuario');
$table->unique('id_usuario');
$table->string('nombre_usuario',255);
$table->string('apellido_usuario',255);
$table->string('foto_usuario', 255);
$table->string('alias',255);
$table->unique('alias');
$table->string('contraseña',255);
$table->text('respuesta_pregunta');
$table->string('telefono_usuario',255);
$table->unique('telefono_usuario');
$table->text('correo');
$table->unique('correo');
$table->integer('id_tipo_usuario')->unsigned();
$table->foreign('id_tipo_usuario')->references('id_tipo_usuario')->on('tipos_usuarios')->onDelete('cascade');
$table->integer('id_cargo_usuario')->unsigned();
$table->foreign('id_cargo_usuario')->references('id_cargo_usuario')->on('cargos_usuarios')->onDelete('cascade');
$table->boolean('estado_usuario');
$table->date('fecha_registro');
$table->date('fecha_retiro')->nullable();
);
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
Schema::dropIfExists('usuarios');
...
第二个是描述用户类型的表格 ...
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB; //para hacer insersion
class CrearTablaTiposUsuarios extends Migration
/**
* Run the migrations.
*
* @return void
*/
public function up()
Schema::create('tipos_usuarios', function (Blueprint $table)
$table->increments('id_tipo_usuario');
$table->unique('id_tipo_usuario');
$table->string('nombre_tipo_usuario', 255);
$table->unique('nombre_tipo_usuario');
$table->text('descripcion_tipo_usuario');
);
// Insert some stuff
DB::table('tipos_usuarios')
->insert(
[
[
'nombre_tipo_usuario' => 'Administrador',
'descripcion_tipo_usuario' => 'Este tipo de usuario se encarga de manejar la aplicación y tiene control total, ademas de ser el unico que puede crear usuarios'
],
[
'nombre_tipo_usuario' => 'Supervisor',
'descripcion_tipo_usuario' => 'Se encarga de ver las actividades de los usuarios , ademas puede agregar clientes y puede asignar clientes a usuarios'
],
[
'nombre_tipo_usuario' => 'Publicador',
'descripcion_tipo_usuario' => 'Este tipo de usuario solo puede agregar conteos a las publiaciones de los clientes'
]
]);
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
Schema::dropIfExists('usuarios');
Schema::dropIfExists('tipos_usuarios');
... 描述用户位置的表格 ...
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB; //para hacer insersion
class CrearTablaCargosUsuarios extends Migration
/**
* Run the migrations.
*
* @return void
*/
public function up()
Schema::create('cargos_usuarios', function (Blueprint $table)
$table->increments('id_cargo_usuario');
$table->unique('id_cargo_usuario');
$table->string('nombre_cargo', 255);
$table->unique('nombre_cargo');
$table->text('descripcion_cargo');
);
// Insert some stuff
DB::table('cargos_usuarios')
->insert(
[
[
'nombre_cargo' => 'Gerente',
'descripcion_cargo' => 'Es el encargado de manejar la empresa de y todas las labores ejecutivas'
],
[
'nombre_cargo' => 'Programador',
'descripcion_cargo' => 'Se encarga de dar soporte tecnico, desarrolla sitios web y aplicaciones.'
],
[
'nombre_cargo' => 'Diseñador',
'descripcion_cargo' => 'Realiza diversos trabajos como diseño de post, logos y otros.'
]
]);
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
Schema::dropIfExists('cargos_usuarios');
...
This last tables must be migrate before "usuarios" to about issues
This is my model
...
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class usuarios extends Model
use HasFactory;
public $timestamps = false; //Esto es necesario para que no se produzcan errores de insersción ya que laravel los usa por predeterminado
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'usuarios';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id_usuario';
public function obtener_tipo_usuario()
return $this->hasOne('App\Models\tipos_usuarios', 'id_tipo_usuario', 'id_tipo_usuario');
public function obtener_cargo_usuario()
return $this->hasOne('App\Models\cargos_usuarios', 'id_cargo_usuario', 'id_cargo_usuario');
public function suspender_usuario()
if ($this->estado_usuario == false)
return 'Este usuario ya ha sido suspendido';
else
$this->estado_usuario = false;
$this->fecha_retiro = date("Y-m-d");
$this->save();
return 'usuario suspendido';
public function activar_usuario()
if ($this->estado_usuario == true)
return 'Este usuario ya esta activo';
else
$this->estado_usuario = true;
$this->fecha_retiro = null;
$this->save();
return 'Usuario dado de alta';
...
这是我的 ususarios 控制器
...
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\usuarios;
use DB;
use Illuminate\Support\Facades\Storage; //para almacenar
use Illuminate\Http\File;
use Illuminate\Validation\Rule;
class UsuariosController extends Controller
/**
* Muestra el formulario para agregar usuarios
* Este debe estar disponible solo para el administrador
*
* @return \Illuminate\Http\Response
*/
public function create()
$tipos_usuarios = DB::table('tipos_usuarios')->where('nombre_tipo_usuario', '!=' ,'Administrador')->get();
$cargos_usuarios = DB::table('cargos_usuarios')->get();
return view('layouts/sistema/usuarios/agregar_usuario', ['tipos_usuarios' => $tipos_usuarios, 'cargos_usuarios' => $cargos_usuarios] );
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $solicitud
* @return \Illuminate\Http\Response
*/
public function store(Request $solicitud)
$solicitud->validate([
'archivo_foto_usuario' =>['required', 'mimes:jpeg,png, webp,jpg', 'dimensions:min_width=50,min_height=50,max_width=200,min_height=200'],
'nombre_usuario' => ['required', 'min:3', 'max:255'],
'apellido_usuario' => ['required', 'min:3', 'max:255'],
'telefono_usuario' => ['required', 'regex:/^\s*(?:\+?(\d1,3))?[-. (]*(\d3)[-. )]*(\d3)[-. ]*(\d4)(?: *x(\d+))?\s*$/','unique:usuarios,telefono_usuario' ],
'alias_usuario' => ['required', 'min:3', 'max:255','unique:usuarios,alias'],
'contraseña_usuario' => ['required','min:8','regex:/^.*(?=.3,)(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[\d\x])(?=.*[!$#%]).*$/'],
'correo_usuario' => ['required', 'regex:/[a-z0-9._%+-]@manilastudio.com$/', 'unique:usuarios,correo'],
'tipo_usuario' => 'required',
'cargo_usuario' => 'required',
], [
'archivo_foto_usuario.required' => 'Se necesita una imagen en formato compatible',
'archivo_foto_usuario.mimes' => 'Formato de imagen no soportado',
'archivo_foto_usuario.dimensions' => 'La imagen debe ser de mimino 50x50 y maximo 200x200',
'nombre_usuario.required' => 'Campo requerido, introduzca al menos 4 caracteres.',
'nombre_usuario.min' => 'Campo requerido, introduzca al menos 4 caracteres.',
'apellido_usuario.required' => 'Campo requerido, introduzca al menos 4 caracteres.',
'apellido_usuario.min' => 'Campo requerido, introduzca al menos 4 caracteres.',
'telefono_usuario.required' => 'Introduza un numero teléfonico valido',
'telefono_usuario.regex' => 'El formato debe ser +50512345678',
'telefono_usuario.unique' => 'Este número ya esta en uso',
'alias_usuario.required' => 'Campo requerido, introduzca al menos 4 caracteres.',
'alias_usuario.min' => 'Campo requerido, introduzca al menos 4 caracteres.',
'alias_usuario.unique' => 'Esta alias ya esta en uso',
'contraseña_usuario.required' => 'Campo requerido, introduzca al menos 8 letras, con números o caracteres',
'contraseña_usuario.min' => 'Campo requerido, introduzca al menos 8 letras, con números o caracteres.',
'contraseña_usuario.regex' => 'La contraseña temporal debe tener letras o números y caracteres',
'correo_usuario.regex' => 'El correo debe usar el dominio manilastudio.com',
'correo_usuario.required' => 'Se necesita asignar un correo electronico',
'correo_usuario.unique' => 'Este correo ya esta en uso'
]);
$nuevo_usuario = new usuarios();
$nuevo_usuario->nombre_usuario = $solicitud->input('nombre_usuario');
$nuevo_usuario->apellido_usuario = $solicitud->input('apellido_usuario');
/**Guardar en un directorio */
if ($solicitud->hasFile('archivo_foto_usuario'))
$nuevo_usuario->foto_usuario = $solicitud->archivo_foto_usuario->store('img/usuarios', 'public');
$solicitud->file('archivo_foto_usuario')->store( 'img/usuarios/');
else
$nuevo_usuario->foto_usuario = 'img/usarios/user.png';
$nuevo_usuario->alias = $solicitud->input('alias_usuario');
$nuevo_usuario->contraseña = $solicitud->input('contraseña_usuario');
$nuevo_usuario->telefono_usuario = $solicitud->input('telefono_usuario');
$nuevo_usuario->correo = $solicitud->input('correo_usuario');
$nuevo_usuario->id_tipo_usuario = $solicitud->input('tipo_usuario');
$nuevo_usuario->id_cargo_usuario = $solicitud->input('cargo_usuario');
$nuevo_usuario->fecha_registro = date("Y-m-d");
$nuevo_usuario->fecha_retiro = null;
$nuevo_usuario->respuesta_pregunta = 'hola';
$nuevo_usuario->estado_usuario = true;
$nuevo_usuario->save();
return redirect('/usuarios');
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\usuarios $id_usuario
* @return \Illuminate\Http\Response
*/
public function edit(usuarios $usuario)
// $usuario = usuarios::find($usuario);
$tipos_usuarios = DB::table('tipos_usuarios')->where('nombre_tipo_usuario', '!=' ,'Administrador')->get();
$cargos_usuarios = DB::table('cargos_usuarios')->get();
return view('layouts/sistema/usuarios/editar_usuario', ['usuario' => $usuario, 'tipos_usuarios' => $tipos_usuarios, 'cargos_usuarios' => $cargos_usuarios]);
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\usuarios $user
* @return \Illuminate\Http\Response
*/
public function update(Request $solicitud, usuarios $usuario)
// $usuario = usuarios::findOrFail($id_usuario);
// dd($usuario->id_usuario);
$valido = $solicitud->validate([
'estado_usuario' =>['required'],
'archivo_foto_usuario' =>['required', 'mimes:jpeg,png, webp,jpg', 'dimensions:min_width=50,min_height=50,max_width=200,min_height=200'],
'nombre_usuario' => ['required', 'min:3', 'max:255'],
'apellido_usuario' => ['required', 'min:3', 'max:255'],
'telefono_usuario' => ['required', 'regex:/^\s*(?:\+?(\d1,3))?[-. (]*(\d3)[-. )]*(\d3)[-. ]*(\d4)(?: *x(\d+))?\s*$/', Rule::unique('usuarios')->ignore($usuario) ],
'alias_usuario' => ['required','min:3','max:255',Rule::unique('usuarios')->ignore($usuario)],
'contraseña_usuario' => ['required','min:8','regex:/^.*(?=.3,)(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[\d\x])(?=.*[!$#%]).*$/', Rule::unique('usuarios')->ignore($usuario)],
'correo_usuario' => ['required', 'regex:/[a-z0-9._%+-]@manilastudio.com$/', /*'unique:usuarios,correo'*/ Rule::unique('usuarios')->ignore($usuario)],
'tipo_usuario' => 'required',
'cargo_usuario' => 'required',
],
[
'estado_usuario.required' => "Debe fijarse un estado para este usuario",
'archivo_foto_usuario.required' => 'Se necesita una imagen en formato compatible',
'archivo_foto_usuario.mimes' => 'Formato de imagen no soportado',
'archivo_foto_usuario.dimensions' => 'La imagen debe ser de mimino 50x50 y maximo 200x200',
'nombre_usuario.required' => 'Campo requerido, introduzca al menos 4 caracteres.',
'nombre_usuario.min' => 'Campo requerido, introduzca al menos 4 caracteres.',
'apellido_usuario.required' => 'Campo requerido, introduzca al menos 4 caracteres.',
'apellido_usuario.min' => 'Campo requerido, introduzca al menos 4 caracteres.',
'telefono_usuario.required' => 'Introduza un numero teléfonico valido',
'telefono_usuario.regex' => 'El formato debe ser +50512345678',
'telefono_usuario.unique' => 'Este número ya esta en uso',
'alias_usuario.required' => 'Campo requerido, introduzca al menos 4 caracteres.',
'alias_usuario.min' => 'Campo requerido, introduzca al menos 4 caracteres.',
'alias_usuario.unique' => 'Esta alias ya esta en uso',
'contraseña_usuario.required' => 'Campo requerido, introduzca al menos 8 letras, con números o caracteres',
'contraseña_usuario.min' => 'Campo requerido, introduzca al menos 8 letras, con números o caracteres.',
'contraseña_usuario.regex' => 'La contraseña temporal debe tener letras o números y caracteres',
'correo_usuario.regex' => 'El correo debe usar el dominio manilastudio.com',
'correo_usuario.required' => 'Se necesita asignar un correo electronico',
'correo_usuario.unique' => 'Este correo ya esta en uso'
]);
$usuario->nombre_usuario = $solicitud->input('nombre_usuario');
$usuario->apellido_usuario = $solicitud->input('apellido_usuario');
/**Guardar en un directorio */
if ($solicitud->hasFile('archivo_foto_usuario'))
Storage::disk('public')->delete($usuario->foto_usuario);
$usuario->foto_usuario = $solicitud->archivo_foto_usuario->store('img/usuarios', 'public');
$solicitud->file('archivo_foto_usuario')->store( 'img/usuarios/');
else
$usuario->foto_usuario = 'img/usarios/user.png';
// dd($solicitud->hasFile('archivo_foto_usuario'));
$usuario->alias = $solicitud->input('alias_usuario');
$usuario->contraseña = $solicitud->input('contraseña_usuario');
$usuario->telefono_usuario = $solicitud->input('telefono_usuario');
$usuario->correo = $solicitud->input('correo_usuario');
$usuario->id_tipo_usuario = $solicitud->input('tipo_usuario');
$usuario->id_cargo_usuario = $solicitud->input('cargo_usuario');
$usuario->fecha_registro = date("Y-m-d");
if ($solicitud->estado_usuario == 0)
$usuario->fecha_retiro = date("Y-m-d");
$usuario->respuesta_pregunta = 'hola';
$usuario->estado_usuario = $solicitud->estado_usuario;
$usuario->save();
return redirect('/usuarios');
...
and this is my view
...
@section('titulo', 'Modificar datos de Usuario')
<x-master>
<div class="container-fluid mt-5">
<div class="text-left">
<h1 class="font-weight-bolder">
Modificar Datos de Usuario
</h1>
</div>
<div class="mt-5">
<form id="formulario-agregar-usuario" class="form" method="POST" action="/usuarios/ $usuario->id_usuario " enctype="multipart/form-data">
@csrf
@method('PUT')
<div class="row">
<div class="col-sm-2">
<div class="border rounded p-2 bg-white">
<div class="border rounded">
<img class="border rounded-circle w-100 img-fluid mr-3" src="/storage/$usuario->foto_usuario" title="Nombre Usuario">
</div>
</div>
<br>
<input class="btn" type="file" name="archivo_foto_usuario">
@error('archivo_foto_usuario') <div class="validacion" > $errors->first('archivo_foto_usuario')</div> @enderror
<div class="mt-4">
<input type="radio" name="estado_usuario" id="activo" value="1" @if ($usuario->estado_usuario == 1 ) checked="checked" @endif>
<label for="activo" class="font-weight-bolder text-uppercase text-success" >Activo</label><br>
<input type="radio" name="estado_usuario" id="suspender" value="0" @if ($usuario->estado_usuario == 0 ) checked="checked"@endif>
<label for="suspender" class="font-weight-bolder text-uppercase text-danger">Suspender</label>
@error('nombre_usuario') <div class="validacion" > $errors->first('estado_usuario')</div> @enderror
</div>
</div>
<div class="col-sm-6 ml-lg-4 ml-sm-0">
<div class="row">
<div class="form-group col-md-6">
<label for="txtNombre_usuario" class="font-weight-bolder text-uppercase">Nombre Usuario</label>
<input id="txtNombre_usuario" class="form-control" type="text" name="nombre_usuario" value=" $usuario->nombre_usuario ">
@error('nombre_usuario') <div class="validacion" > $errors->first('nombre_usuario')</div> @enderror
</div>
<div class="form-group col-md-6">
<label for="txtApellido_correo" class="font-weight-bolder text-uppercase">Apellido Usuario</label>
<input id="txtApellido_usuario" class="form-control" type="text" name="apellido_usuario" value=" $usuario->apellido_usuario ">
@error('apellido_usuario') <div class="validacion" > $errors->first('apellido_usuario')</div> @enderror
</div>
<div class="form-group col-md-6">
<label for="txtTelefono_Usuario" class="font-weight-bolder text-uppercase">Telefono Usuario</label>
<input id="txtTelefono_Usuario" type="tel" class="form-control" name="telefono_usuario" placeholder="ejemplo +505812345678" value=" $usuario->telefono_usuario ">
@error('telefono_usuario') <div class="validacion" > $errors->first('telefono_usuario')</div> @enderror
</div>
<div class="form-group col-md-6">
<label for="txtemail" class="font-weight-bolder text-uppercase">Correo</label>
<input id="txtemail" class="form-control" type="email" name="correo_usuario" value=" $usuario->correo_usuario ">
@error('correo_usuario') <div class="validacion" > $errors->first('correo_usuario')</div> @enderror
</div>
<div class="form-group col-md-6">
<label for="sltTipo_Usuario" class="font-weight-bolder text-uppercase">Tipo de Usuario</label>
<select id="sltTipo_Usuario" class="form-control" name="tipo_usuario" >
@foreach ($tipos_usuarios as $tipo)
<option value="$tipo->id_tipo_usuario" @if ($tipo->id_tipo_usuario == $usuario->id_tipo_usuario) selected="selected" @endif>$tipo->nombre_tipo_usuario </option>
@endforeach
</select>
</div>
<div class="form-group col-md-6">
<label for="sltCargo_Usuario" class="font-weight-bolder text-uppercase">Cargo de Usuario</label>
<select id="sltCargo_Usuario" class="form-control" name="cargo_usuario">
@foreach ($cargos_usuarios as $cargo)
<option value="$cargo->id_cargo_usuario" @if ($cargo->id_cargo_usuario == $usuario->id_cargo_usuario) selected="selected" @endif>$cargo->nombre_cargo</option>
@endforeach
</select>
</div>
<div class="form-group col-md-6">
<label for="txtAlias_usuario" class="font-weight-bolder text-uppercase">Alias Usuario</label>
<input id="txtAlias_usuario" class="form-control" type="text" name="alias_usuario" value="@if (old('alias_usuario') !== null ) old('alias_usuario')@else $usuario->alias@endif">
@error('alias_usuario') <div class="validacion" > $errors->first('alias_usuario')</div> @enderror
</div>
<div class="form-group col-md-6">
<label for="txtcontraseña" class="font-weight-bolder text-uppercase">Contraseña Temporal</label>
<input id="txtcontraseña" class="form-control" type="password" name="contraseña_usuario" value=" $usuario->contraseña">
@error('contraseña_usuario') <div class="validacion" > $errors->first('contraseña_usuario')</div> @enderror
<div class="validacion" ></div>
</div>
</div>
<div class="text-left">
<button type="submit" class="btn btn-primary">Modificar Usuario</button>
</div>
</div>
</div>
</form>
</div>
</div>
</x-master>
...
这是我得到的错误
SQLSTATE[42S22]:找不到列:1054 'where 子句'中的未知列'alias_usuario'(SQL:从usuarios
中选择计数(*)作为聚合,其中alias_usuario
= rytertertcc 和id_usuario
4 )
我查看了 laravel 官方文档https://laravel.com/docs/8.x/validation#rule-unique 所以我开始实施这个 Rule::unique('usuarios')->ignore($usuario)] 所以如果我更新一个用户别名,它是唯一的数据片段,但没有电子邮件或电话也是唯一的数据片段,我应该没有这个问题,
与这个Laravel: Validation unique on update相关的另一个问题对这个问题没有用。
如果可能的话,我非常感谢您的帮助,非常感谢。
【问题讨论】:
刚刚添加了您要询问的密钥。我只是觉得很难理解 【参考方案1】:由于输入名称与列名不匹配,因此您必须在创建规则时传递列名。根据documentation,如果您的数据库使用的列与您传递的列不同,那么您还需要传递列名:
Rule::unique('usuarios', 'alias')->ignore($usuario)
【讨论】:
非常感谢 :) 这就是解决问题的方法现在我可以毫无问题地更新,只是一个简单的问题,你认为我应该在表单中保留字段的名称吗?模型中的那些?只是为了保持一致性。 我发现在大多数情况下字段名称相同会有所帮助。更容易追踪事情,以及在数据库和帖子字段之间映射字段。【参考方案2】:你也可以这样做:
我不清楚你的数据库结构,但我可以举个例子,如下所示:
users
是一个表名。
name 是您要验证的列。
'name' => 'unique:users,name,' . request('id')
【讨论】:
【参考方案3】:在更新功能中你可以使用
'telefono_usuario' => 'unique:usuarios,telefono_usuario,' . $usuario->id_usuario,
telefono_usuario 作为您的字段名称
unique:usuarios 是你的模型
$usuario->id_usuario是你要更新的id
【讨论】:
这导致内部查询引擎找不到字段 SQLSTATE[42S22] 的错误:找不到列:1054 Unknown column 'id' in 'where Clause' (SQL: select count(* ) 作为来自usuarios
的聚合,其中telefono_usuario
= +00112345678 和id
5)
看起来您没有在模型中定义主键。如果您的表主键是“id_usuario”,请尝试protected $primaryKey = 'id_usuario';以上是关于如何验证记录更新中的唯一字段的主要内容,如果未能解决你的问题,请参考以下文章