在我們的Web應用程式,我們希望有一個簡單的封裝基座cms,對于具有我們有users,packages,features并user_package在資料庫表
- 每個
users都可以有一個package我們user_package為此創建 的 - 每個
user_package屬于許多users - 每個
user_package都有packages - 每個
packages都可以有很多features我們創建的features表 - 每個
features屬于許多packages
當我嘗試讓用戶打包時,我認為它應該是:
user->user_package->package->[feature]
我的模型:
class User extends Authenticatable
{
//...
public function user_package()
{
return $this->hasOne(UserPackage::class);
}
}
class UserPackage extends Model
{
public function package()
{
return $this->belongsTo(Package::class);
}
}
class Package extends Model
{
public function feature(): HasMany
{
return $this->hasMany(Features::class);
}
}
class Features extends Model
{
public function package(): BelongsToMany
{
return $this->belongsToMany(Package::class);
}
}
遷移:
Schema::create('packages', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description')->nullable()->default('');
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();
});
Schema::create('features', function (Blueprint $table) {
$table->id();
$table->foreignId('packages_id')->nullable()
->constrained()->cascadeOnUpdate()
->cascadeOnDelete();
$table->string('title');
$table->text('description')->nullable()->default('');
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();
});
Schema::create('user_packages', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()
->cascadeOnUpdate()
->cascadeOnDelete();
$table->foreignId('packages_id')->nullable()->constrained()
->cascadeOnUpdate()
->cascadeOnDelete();
$table->longText('features')->nullable()->default('');
$table->integer('price');
$table->dateTime('start_date');
$table->dateTime('end_date');
$table->timestamp('created_at')->useCurrent();
$table->timestamp('update_at')->useCurrent();
});
現在,當我嘗試獲取資料時,我得到null了package關系
Route::get('/test',function(){
dd(auth()->user()->with(['user_package'=>function($query){
$query->with(['package'=>function($package){
$package->with('feature')->get();
}])->first();
}])->first());
});
輸出:
App\Models\User {#1319 ▼
#hidden: array:2 [?]
#casts: array:1 [?]
#connection: "mysql"
#table: "users"
...
#relations: array:1 [▼
"user_package" => App\Models\UserPackage {#1570 ▼
#connection: "mysql"
#table: "user_packages"
...
#dispatchesEvents: []
#observables: []
#relations: array:1 [▼
"package" => null
]
...
}
uj5u.com熱心網友回復:
我認為您的問題的癥結在于獲取嵌套關系,這很簡單,auth()->user()->with('user_package.package.feature')但是您的關系存在問題。
你Package和之間的關系Feature已經破裂;由于該features表有一package_id列,根據定義,一個特性不能“屬于多個”包。
class User extends Authenticatable
{
public function user_package(): HasOne
{
return $this->hasOne(UserPackage::class);
}
}
class UserPackage extends Model
{
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function package(): BelongsTo
{
return $this->belongsTo(Package::class);
}
}
class Package extends Model
{
public function features(): HasMany
{
return $this->hasMany(Feature::class);
}
/**
* It never hurts to define both ends of the relationship
* even if they aren't being used
*/
public function user_packages(): HasMany
{
return $this->hasMany(UserPackage::class);
}
}
class Feature extends Model
{
public function package(): BelongsTo
{
return $this->belongsTo(Package::class);
}
}
現在,使用該關系,您可以獲得包功能:
dump(Auth::user()->load('user_package.package.features'))
你有一些命名問題,我在上面的例子中糾正了 - 回傳單個模型的關系方法應該是單數,其他應該是復數。類名不應該是復數詞(即Feature不是Features.)
一般來說,如果它所做的只是連接兩個模型,則不需要創建樞軸類。我不打算討論這個問題,因為它會提供更長的答案,但需要牢記這一點。
這是個人品味的問題,但您的類名應該只有一個詞(即Subscription而不是UserPackage),因為這樣可以更直觀地找出關系名稱之類的東西。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/396409.html
