Generating Uuid as Primary Key - php

Please i am having an issue generating a uuid as primary key in my user model. i always PHP Error: Class 'App/Traits/boot' not found in C:/xampp/htdocs/twingle/app/Traits/UsesUuid.php on line 11. Tried various method but this error persist
User Model (App\User)
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Traits\UsesUuid;
class User extends Authenticatable
{
use Notifiable,UsesUuid;
protected $keyType = 'string';
public $incrementing = false;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
which use a Trait
UseUuid(App\Traits)
<?php
namespace App\Traits;
use Ramsey\Uuid\Uuid;
trait UsesUuid
{
public static function UsesUuid()
{
boot::creating(function ($model) {
$model->setAttribute($model->getKeyName(), Uuid::uuid4());
});
}
}
User mIgration
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Please any help will be deeply appreciated. thanks

Your trait code looks really inconsistent. It should look something like this:
namespace App\Traits;
use Ramsey\Uuid\Uuid;
trait UsesUuid
{
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->setAttribute($model->getKeyName(), Uuid::uuid4());
});
}
}
That way when the trait is used in a model, it will automatically hook into that model's creating event, and will make sure the primary key is generated as a UUID.

Go for a model Observer. It's much cleaner and the perfect fit. https://laravel.com/docs/5.8/eloquent#observers

Related

Laravel 9 Eloquent relations with UUID

why the user_id is set to ? in Eloquent hasOne relation's sql query
"select * from `files` where `files`.`user_id` = ? and `files`.`user_id` is not null",
here's the model code
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable implements MustVerifyEmail
{
use HasApiTokens, HasFactory, SoftDeletes,HasUuids;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'email',
];
protected $keyType = 'string';
public $incrementing = false;
/**
* The attributes that should be hidden for serialization.
*
* #var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
'id'=>'string',
];
public function profile_picture(){
return $this->hasOne(File::class);
}
}
and the file model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class File extends Model
{
use HasFactory,HasUuids;
protected $fillable = [
'name',
'content',
'extension',
];
protected $keyType = 'string';
public $incrementing = false;
public function user(){
return $this->belongsTo(User::class);
}
}
migrations:
Schema::create('users', function (Blueprint $table) {
$table->uuid('id')->primary()->unique();
$table->string('name');
$table->string('email');
$table->softDeletes($column = 'deleted_at', $precision = 0);
$table->rememberToken();
$table->timestamps();
});
Schema::create('files', function (Blueprint $table) {
$table->uuid('id')->primary()->unique();
$table->string('name');
$table->string('extension');
$table->uuid('user_id')->nullable();
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
Instead of using auto-incrementing integers as your Eloquent model's primary keys, you may choose to use UUIDs instead. UUIDs are universally unique alpha-numeric identifiers that are 36 characters long.
code php explain the problem and the corect code.

SQLSTATE[42P01]: Undefined table: 7

I'm newbiу in laravel 9. I just want create simple blog with the tables:users, stories,comments.I have next relationship
users->stories(One To Many, hasMany laravel) ,
stories->users(One To Many (Inverse) / Belongs To),
users->comments(One To Many, hasMany laravel) ,
comments->users(One To Many (Inverse) / Belongs To),
stories->comments(One To Many, hasMany laravel) ,
comments->stories(One To Many (Inverse) / Belongs To).
class User
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use App\Models\Story;
use App\Models\Comment;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* #var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function stories()
{
return $this->hasMany(Story::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
}
class Story:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Model\User;
use App\Model\Comment;
class Story extends Model
{
use HasFactory;
protected $fillable = ['description', 'textStory'];
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
}
class Comment:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\Story;
use App\Models\User;
class Comment extends Model
{
use HasFactory;
public function storyFunction()
{
return $this->belongsTo(Story::class);
}
public function userFunction()
{
return $this->belongsTo(User::class);
}
}
Stories migration:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('stories', function (Blueprint $table) {
$table->id();
$table->string('description');
$table->text('textStory');
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('stories');
}
};
Comments migration:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->text('textComment');
//$table->foreignId('story_id')->constrained('stories')->onDelete('cascade');
/*$table->foreign('story_id')
->references('id')->on('stories')
->onDelete('cascade');*/
$table->timestamps();
});
Schema::table('comments', function(Blueprint $table) {
$table->foreignId('user_id')->constrained()->onDelete('cascade');
});
Schema::table('comments', function(Blueprint $table) {
$table->foreignId('story_id')->constrained()->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('comments');
}
};
But when i run php artisan migrate or php artisan migrate:refresh i see next error:
SQLSTATE[42P01]: Undefined table: 7 ?z?????С?s??: ??NВ????N??╡?????╡ "stories
" ???╡ N?N?NЙ?╡N?NВ??N??╡NВ (SQL: alter table "comments" add constraint "comment
s_story_id_foreign" foreign key ("story_id") references "stories" ("id") on dele
te cascade)
But if i delete or comment next strings in comments migration file:
Schema::table('comments', function(Blueprint $table) {
$table->foreignId('story_id')->constrained()->onDelete('cascade');
});
Migration run succesfull.
Please help me resolve this error.
Most likely, the table that Laravel finds using the conventions is missing. Specify the table explicitly as an argument to the constrained method like this Schema::table('comments', function(Blueprint $table) {
$table->foreignId('story_id')->constrained('Your_table_name')->onDelete('cascade');
});Foreign Key Constraints

Login issues - Credentials do not match in Laravel

Hi Everyone!
I'm using Laravel-8 with Laravel UI. I can able to register any user that is not a problem, but when I log out & try to login again with the same user Credential then I got this error message!
Screenshot-1:
Here is my Database User Table:
Migrations : create_users_table.php
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->nullable();
$table->timestamp('email_verified_at')->nullable();
$table->string('password')->nullable();
$table->string('avater')->nullable();
$table->rememberToken();
$table->timestamps();
});
}
UserController.php
public function uploadAvater(Request $request){
if($request->hasFile('image')){
$filename = $request->image->getClientOriginalName();
$request->image->storeAs('images', $filename);
User::find(1)->update(['avater' => $filename]);
}
return redirect()->back();
}
Models-> User.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt($password);
}
public function getNameAttribute($name)
{
return ucfirst($name);
}
}
?>
Does anyone have an idea why I can't able to login in? where is the problem? thanks!
Laravel/ui already hashes the password field when registering. So by using an Eloquent Mutator to hash the password field, you are essentially hashing it twice.
You'll have to either remove the mutator (setPasswordAttribute method) or edit the create() method in RegisterController.

Too few arguments to function Illuminate\Database\Eloquent\Model::setAttribute(), 1 passed

i want to ask about error "Too few arguments to function Illuminate\Database\Eloquent\Model::setAttribute(), 1 passed "
i try to register users, i use php artisan make:auth to build my authentication. But, i add one field in users migration. and i try to use uuid. this is my code :
User Model
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Traits\Uuids;
class User extends Authenticatable
{
use Notifiable;
use Uuids;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $guarded = ['id'];
protected $table = 'users';
protected $fillable = [
'name', 'email', 'password','phone_number',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
Register Controller
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Http\Request;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'phone' => 'required|numeric|min:8',
'password' => 'required|string|min:6|confirmed',
'password_confirmation' => 'required|same:password',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'phone_number' => $data['phone'],
'password' => Hash::make($data['password']),
]);
}
}
Users Migration
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->uuid('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->integer('phone_number');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
Uuids Trait
<?php
namespace App\Traits;
trait Uuids
{
/**
*
*/
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->{$model->uuid} =
str_replace('-', '', \Uuid::generate(4)->string);
});
}
}
Please give me advice. Thank You.
I can't find any reference about property or magic property you wrote as below (like a method getUuidAttribute for example)
$model->{$model->uuid} = str_replace('-', '', \Uuid::generate(4)->string);
So, I assume above code would compiled as
$model->{null} = str_replace('-', '', \Uuid::generate(4)->string);
I guess you're looking for $model->id which has the type of database column as a uuid. But, obviously, you can't have a dynamic database column name as it is wrong at all. Example of dynamic column if your snippet is working properly
$model->'6b324d55-433c-455a-88b6-feb2ee6c3709' = 'c3bec822-e5ee-4d91-b1a3-f5f552fd004a';
Something isn't right, right? It would be better if it look like this.
$model->id = 'c3bec822-e5ee-4d91-b1a3-f5f552fd004a';
And of course, make your latest snippet be something as follow
<?php
namespace App\Traits;
trait Uuids {
// to make model run this 'boot' method, append it with your trait name
protected static function bootUuids() { // <-- bootUuids
// parent::boot();
static::creating(function ($model) {
$model->id = str_replace('-', '', \Uuid::generate(4)->string);
});
}
}
Assuming your tables use UUID for primary key
$table->uuid('id')->primary();
Review your trait by setting the value directly to the id
<?php
namespace App\Traits;
use Illuminate\Support\Str;
trait UsesUuid
{
protected static function bootUsesUuid()
{
static::creating(function ($model) {
if (! **$model->id**) {
**$model->id** = (string) Str::uuid();
}
});
}
public function getIncrementing()
{
return false;
}
public function getKeyType()
{
return 'string';
}
}
Now use trait in your model
<?php
namespace App\Models;
use App\Traits\UsesUuid;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Group extends Model
{
use HasFactory;
**use UsesUuid;**
The full post is here
Create good solutions out there guys :)

Relation one to many it doesn't work

https://imgur.com/a/ob9rjIz
There are two tables one called user and another called user_relation_user
My relation is an user to many user_relation_user and in my migration. I want to create 10 user with php artisan tinker so i run factory(App\User::class, 10)->create(); at the end i access to my database so do select * from users there are 10 users but in user_relation_user isn't 10 id or it's empty
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Administrator extends Model
{
protected $table = 'user_relation_user';
protected $primaryKey = 'id';
protected $fillable = ['user_id'];
public function users(){
return $this->belongsTo(User::class,'user_id');
}
}
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function administrator(){
return $this->hasMany(Administrator::class,'user_id');
}
}
//hasMany
My migration
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUserRelationUserTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('user_relation_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('user_id_admin')->unsigned();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*foreign
* #return void
*/
public function down()
{
Schema::dropIfExists('user_relation_user');
}
}
The relation you define is correct,you just need to define a relation in user model as well.
Example:
Suppose you are developing a blog system where user can post blogs.
then there will be two models user model and blog model
In User model you have to define user relation as below:
public function blogs()
{
return $this->hasmany(Blog::class);
}
Then in blogs model
public function users()
{
return $this->belongsTo(User::class);
}

Categories