سلام و وقت بخیر
ساختار جداول :
users
id
name
roles
id
name
properties
id
description
role_user
id
user_id
role_id
property_id
و روابط :
class User extends Model{
public function roles(){
return $this->belongsToMany(Role::class , 'role_user')->withPivot(['property_id']);
}
}
class Role extends Model{
public function users(){
return $this->belongsToMany(User::class , 'role_user')->withPivot(['property_id']);
}
}
class RoleUser extends Pivot{
public function property(){
return $this->belongsTo(Property::class);
}
}
همه چیز اوکیه ولی وقتی میخوام role های یه user رو به اینصورت بگیرم به مشکل میخورم :
$result = User::with('roles')->findOrFail(1);
در واقع درسته ولی من میخوام property هم لود شه که نمیشه
حتی اینم تست کردم ولی نشد :
$result = User::with('roles.property')->findOrFail(1);
در واقع یه همچین چیزی میخوام برگرده :
{
"data": {
"id": 1,
"name": "ali",
"roles": [
{
"id": 1,
"name": "test",
"pivot": {
"user_id": 1,
"role_id": 1,
"property_id": 1 ,
"property" : {
"id" : 1 ,
"description" : "test"
}
}
}
]
},
"status": "success"
}
ممنون میشم کمک کنید
وقتی میزنی roles.property یعنی توی relation roles یک رابطهای هست به اسم property که شما نداری.
اگر خروجی زیر رو میخوای باید اینکار رو بکنی
[
{
"id": 1,
"name": "reza",
"email": "info@rp76.ir",
"email_verified_at": null,
"created_at": null,
"updated_at": null,
"roles": [
{
"id": 1,
"name": "admin",
"created_at": null,
"updated_at": null,
"pivot": {
"user_id": 1,
"role_id": 1,
"property_id": 1
},
"property": {
"id": 1,
"description": "zizigolo\r\n",
"created_at": null,
"updated_at": null,
"laravel_through_key": 1
}
}
]
}
]
class Role extends Model
{
use HasFactory;
public function users(){
return $this->belongsToMany(User::class , 'role_user')->withPivot(['property_id']);
}
public function property(){
return $this->hasOneThrough(Property::class,RoleUser::class,'property_id','id');
}
}
البته من عادت دارم برای جداول pivot هم مدل درست میکنم.
ولی شما اینکار رو نمیکنید.
نکتهای که باید بهش توجه کنی اینه که اطلا این ساختار خراب و اشتباه هست.
چرا گفتم خرابه؟
شما گفتی یه کاربر هست که Role شماره یک رو داره به اسم Admin و امدی توی جدول دیگهای گفتی این کاربر با اون role وصل بشه به این property ها توی جدول واسط!
خب Admin همیشه ادمین هست نیاز نیست براش به ازای هر کاربر توی جدول واسط یکسری اطلاعات ایجاد کنی.
وارد مباحث پیشفرته این تسک نمیشم چون من دقیقا نمیدونم شما چی نیاز دارید. مثلا اگر بگید خب شاید بخواد یه property اضافه بده بهش یا یچیزی ازش بگیره و .... اینطوری خیلی طولانی میشه بحث.
راحت ترین کار اینه شما بیاید
بگید این role هارو داریم و این role ها این property هارو داره.
حالا هر یوزر در یک لحظه فقط میتونی یک role داشته باشه.
دیتابیس:
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('role_id')->default('3');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Schema::create('role_properties', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('role_id');
$table->unsignedBigInteger('property_id');
$table->timestamps();
});
البته باز هم این که یه جدول باشه برای role فقط توش اسم باشه و یه جدول دیگه برای property ها که باز یه اسم توشه اضافه کاریه ولی خب اگر دوست داری اینطوری پیش بری مشکلی نیست.
امیدوارم همین ها کافی باشه و نیاز به رابطه هاش نداشته باشید و خودتون بتونید اون رو اضافه کنید.
سیستم پیشنهادی خودم:
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('role_id')->default('3');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('scopes',4184);
$table->timestamps();
});
توی سیستم من چون همه چیز کاربر هست و توی هر درخواست نیازه اطلاعات مربوط به سطح دسترسی رو فراخوانی کنم ترجیح میدم با کمترین درخواست بهش برسم و دیتابیس رو مشغولش نکنم.
اطلاعات scope به صورت ارایه ذخیره شده!
@Rp76
ممنون از وقتی که گذاشتین.
وقتی این رو میزنم :
$result = User::with('roles')->findOrFail(1);
منطقا خطایی نداره ولی نمیره property رو بیاره صرفا role هارو میاره
و وقتی اینطوری میزنم :
$result = User::with('roles.property')->findOrFail(1);
این ارور میده و میگه رابطه ای به نام property در User وجود نداره که منطقیه چون این رابطه داخل pivot تعریف شده
حالا من میخوام property رو بیاره یعنی یه چیزی مثل همون json ای که پیام قبلی فرستادم و دقیقا نمیدونم چی بزنم تا همچین چیزی خروجی بده
البته پیشتر یه پکیج پیدا کردم ولی میخوام بدونم بدون پکیج چطوری پیاده کنم؟
https://github.com/ajcastro/eager-load-pivot-relations
خوب بهتر نیست اول find کنید کابر رو وقتی پیدا کرد بگین رابطه های اونو نشون بده؟
شما ظاهرا اول گفتیم راطه نشون بده بعد کاربر پیدا کردین
وقتی میزنی roles.property یعنی توی relation roles یک رابطهای هست به اسم property که شما نداری.
اگر خروجی زیر رو میخوای باید اینکار رو بکنی
[
{
"id": 1,
"name": "reza",
"email": "info@rp76.ir",
"email_verified_at": null,
"created_at": null,
"updated_at": null,
"roles": [
{
"id": 1,
"name": "admin",
"created_at": null,
"updated_at": null,
"pivot": {
"user_id": 1,
"role_id": 1,
"property_id": 1
},
"property": {
"id": 1,
"description": "zizigolo\r\n",
"created_at": null,
"updated_at": null,
"laravel_through_key": 1
}
}
]
}
]
class Role extends Model
{
use HasFactory;
public function users(){
return $this->belongsToMany(User::class , 'role_user')->withPivot(['property_id']);
}
public function property(){
return $this->hasOneThrough(Property::class,RoleUser::class,'property_id','id');
}
}
البته من عادت دارم برای جداول pivot هم مدل درست میکنم.
ولی شما اینکار رو نمیکنید.
نکتهای که باید بهش توجه کنی اینه که اطلا این ساختار خراب و اشتباه هست.
چرا گفتم خرابه؟
شما گفتی یه کاربر هست که Role شماره یک رو داره به اسم Admin و امدی توی جدول دیگهای گفتی این کاربر با اون role وصل بشه به این property ها توی جدول واسط!
خب Admin همیشه ادمین هست نیاز نیست براش به ازای هر کاربر توی جدول واسط یکسری اطلاعات ایجاد کنی.
وارد مباحث پیشفرته این تسک نمیشم چون من دقیقا نمیدونم شما چی نیاز دارید. مثلا اگر بگید خب شاید بخواد یه property اضافه بده بهش یا یچیزی ازش بگیره و .... اینطوری خیلی طولانی میشه بحث.
راحت ترین کار اینه شما بیاید
بگید این role هارو داریم و این role ها این property هارو داره.
حالا هر یوزر در یک لحظه فقط میتونی یک role داشته باشه.
دیتابیس:
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('role_id')->default('3');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Schema::create('role_properties', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('role_id');
$table->unsignedBigInteger('property_id');
$table->timestamps();
});
البته باز هم این که یه جدول باشه برای role فقط توش اسم باشه و یه جدول دیگه برای property ها که باز یه اسم توشه اضافه کاریه ولی خب اگر دوست داری اینطوری پیش بری مشکلی نیست.
امیدوارم همین ها کافی باشه و نیاز به رابطه هاش نداشته باشید و خودتون بتونید اون رو اضافه کنید.
سیستم پیشنهادی خودم:
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('role_id')->default('3');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('scopes',4184);
$table->timestamps();
});
توی سیستم من چون همه چیز کاربر هست و توی هر درخواست نیازه اطلاعات مربوط به سطح دسترسی رو فراخوانی کنم ترجیح میدم با کمترین درخواست بهش برسم و دیتابیس رو مشغولش نکنم.
اطلاعات scope به صورت ارایه ذخیره شده!
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟