Mối quan hệ đa hình trong laravel eloquent
Mối quan hệ đa hình giúp chúng ta xử lý rất nhiều vấn đề liên quan đến cơ sở dữ liệu như liết kết giữa 2 bảng và lấy data
Đầu tiên là tìm hiểu về morphOne dùng để lấy liên kết 1-1 giữa 2 bảng :
Bài toán đặt ra là chúng ta có 1 bảng dữ liệu slug liên quan đến việc tạo slug cho bài viết , danh mục bài viết ,video
Migrate tạo slug như sau :
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('slugs', function (Blueprint $table) {
$table->id();
$table->string('slug')->unique()->index();
$table->morphs('slugable');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('slugs');
}
};
Migrate bảng post :
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('name', length: 255);
$table->longText('content');
$table->unsignedBigInteger('user_id')->default(1);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('posts');
}
};
Trong file model với Post
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
/**
* The attributes that aren't mass assignable.
*
* @var array
*/
protected $guarded = ['id'];
public function slugs()
{
return $this->morphOne(Slug::class, 'slugable');
}
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
}
với Slug :
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Slug extends Model
{
protected $guarded = ['id'];
public function slugable()
{
return $this->morphTo('slugable');
}
}
Oke vây là xong giờ đến phần create và update ,delete thì làm tương tự :
$data['name'] = 'My post title';
$data['content'] = 'Content for post title';
$data['user_id'] = 1;
$post = Post::create($data);
// $post->slugs()->create(['slug' => 'post-123456778']);
// $post = Post::find(6);
$post->slugs()->create(['slug' => 'post-11234']);
$post->images()->create(['url' => 'post-123456778']);
$post->images()->createMany([
['url' => 'post-123456778'],
['url' => 'post2']
]);
Trong controller khi ta muốn xử lý lấy thông tin bài viết hay thông tin về category ta có thể code như sau :
<?php
namespace App\Http\Controllers;
use App\Models\Image;
use App\Models\Post;
use App\Models\Slug;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
class SiteController extends Controller
{
public function index(Request $request)
{
$data = Slug::where('slug', '=', 'post-11234')->firstOrFail();
dd($data->slugable->name);
// $post = Post::find(6);
// dd($post->slugs());
}
public function images()
{
$data = Post::find(2);
foreach ($data->images as $key => $value) {
if ($value->url == 'post2-123') {
$value->url = 'post2-12345678';
$value->save();
}
}
}
public function imageslugable(Request $request)
{
$data = Image::where('url', '=', 'post2-12345678')->firstOrFail();
dd($data->imageable->name);
}
public function user_image(Request $request)
{
$user = User::find(1);
dd($user->post_image()->paginate(2));
}
public function hasuserimage(Request $request)
{
$data = User::withWhereHas('post_image', function (Builder $query) {
$query->where('url', '=', 'post-123456778');
})->get();
dd($data);
}
}
Mục function index ta sẽ lấy các thông tin cần thiết như slugable và thông tin liên quan đến post hoặc category hay images