Laravel 9 Eloquent relations with UUID - php

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.

Related

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'majors.user_id' in 'where clause' (SQL: select * from `majors` where `majors`.`user_id` = 1

I want to display user's major. I've defined relationship between user-major and i created foreignId 'major_id' in user's table. I migrated all migrations successfully. But when i want to display user's major it return error
SQLSTATE[42S22]: Column not found: 1054 Unknown column
'majors.user_id' in 'where clause' (SQL: select * from majors where
majors.user_id = 1 and majors.user_id is not null limit 1)
model Major.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Major extends Model
{
use HasFactory;
// protected $primaryKey = 'info_id';
protected $guarded=['id'];
public function faculty(){
return $this->belongsTo(Faculty::class);
}
public function user(){
return $this->belongsTo(User::class);
}
}
model 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;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
// protected $fillable = [
// 'name',
// 'email',
// 'password',
// ];
protected $guarded=['id'];
/**
* 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 getRouteKeyName()
{
return 'name';
}
public function score(){
return $this->hasMany(Score::class);
}
public function major(){
return $this->hasOne(Major::class);
}
}
2021_05_21_042431_create_majors_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMajorsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('majors', function (Blueprint $table) {
$table->id();
$table->foreignId('faculty_id')->constrained();
$table->string('nama_jurusan');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('majors');
}
}
2022_05_22_000000_create_users_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('major_id');
// $table->foreignId('major_id')->constrained('majors');
$table->foreign('major_id')->references('id')->on('majors');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->bigInteger('nrp');
$table->string('address');
$table->integer('generation');
// $table->string('major');
// $table->string('faculty');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
index.blade.php to display user's major
#extends('dashboard.layouts.main')
#section('container')
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1>Biodata</h1>
{{-- <h1 class="h2">Welcome back, {{auth()->user()->name}}</h1> --}}
{{-- <div class="btn-toolbar mb-2 mb-md-0"> --}}
</div>
<div class="container">
<h4>Nama: {{auth()->user()->name}}</h4>
<h4>Email: {{auth()->user()->email}}</h4>
<h4>Alamat: {{auth()->user()->address}}</h4>
<h4>Angkatan: {{auth()->user()->generation}}</h4>
<h4>Jurusan: {{auth()->user()->major->nama_jurusan}}</h4>
<h4>Fakultas: {{auth()->user()->major->faculty->nama_fakultas}}</h4>
</div>
#endsection
in the user modal change the relationship to
public function major(){
return $this->belongsTo(Major::class);
}
And When select write
User::with('major')->get();
I think what you have done till is right need to add proper fillable value in models.
you user model should be like this
<?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;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
'major_id',
'nrp',
'address',
'generation'
];
protected $guarded=['id'];
/**
* 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 getRouteKeyName()
{
return 'name';
}
public function score(){
return $this->hasMany(Score::class);
}
public function major(){
return $this->hasOne(Major::class,'id','major_id');
}
}
Note : Laravel default conventions are looking user_id on majors table but its not there thats the issue for this case so add your convention to user model like this
public function major(){
return $this->hasOne(Major::class,'id','major_id');
}

Laravel One to One relation error don't know why?

Error Showing
Symfony\Component\HttpFoundation\Response::setContent(): Argument #1 ($content) must be of type ?string, Illuminate\Database\Eloquent\Relations\HasOne given, called in G:\Laravel\practice-1\vendor\laravel\framework\src\Illuminate\Http\Response.php on line 72
User Model
<?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;
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 book()
{
# code...
return $this->hasOne(Book::class);
}
}
Book Migration
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateBooksTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('books', function (Blueprint $table) {
$table->id();
$table->integer('user_id')->unsigned();
$table->string('title');
$table->string('abut');
$table->float('amount', 8, 2);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('books');
}
}
Route::get('/user/{id}/book', function ($id) {
return User::find($id)->book();
});
I have no idea why I am seeing this error. I have also looked at the documentation but no help was found.
Your definitions are good. But this statement:
return User::find($id)->book();
returns a Illuminate\Database\Eloquent\Relations\HasOne object.
That is no valid content for a response. Try to change it to:
return User::find($id)->book;

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.

Generating Uuid as Primary Key

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

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