提问人:Ryan H 提问时间:11/8/2023 更新时间:11/17/2023 访问量:140
Laravel 10 morph许多不检索应报告的模型
Laravel 10 morphMany not retrieving notifiable models
问:
我需要一些关于我的关系的帮助。我正在构建一项功能,允许用户通过不同的通知渠道获取各种类型的通知。这是我的模型:morphMany
NotificationNotifiable
- 这定义了 ID、notifiable_type、notifiable_id 和 notification_type_id 列,这是跟踪用户已启用并希望接收通知的所有类型的表。NotificationChannel
- 只是一个简单的表格来定义渠道,例如:推送、电子邮件、短信NotificationType
- 用于定义通知类型及其相应的支持notification_channel_id列的表格,也许通过电子邮件进行一般营销是一种类型。
我已经选择了,因为我可能还有其他模特也希望收到通知。
NotificationNotifiable
我能够从我的控制器(通知首选项)中检索数据,但是尽管有用户的条目,但我在我的关系下没有看到它,它是空的,这是我的模型:notificationNotifiable
- 型:
NotificationNotifiable
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class NotificationNotifiable extends Model
{
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'notification_notifiables';
/**
* The attributes that aren't mass assignable.
*
* @var array
*/
protected $guarded = [
'id'
];
/**
* Get the parent notifiable model.
*/
public function notifiable(): MorphTo
{
return $this->morphTo();
}
/**
* Get the notification type for this model.
*/
public function notificationType(): BelongsTo
{
return $this->belongsTo(NotificationType::class);
}
}
- 型:
NotificationChannel
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class NotificationChannel extends Model
{
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'notification_channels';
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'display_order' => 'integer',
'requires_subscription' => 'boolean',
'is_popular' => 'boolean',
'is_recommended' => 'boolean',
'is_enabled' => 'boolean',
];
/**
* Get the notification types for this model.
*/
public function notificationTypes(): HasMany
{
return $this->hasMany(NotificationType::class);
}
}
- 型:
NotificationType
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class NotificationType extends Model
{
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'notification_types';
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'display_order' => 'integer',
];
/**
* The accessors to append to the model's array form.
*
* @var array
*/
protected $appends = [
'has_notifiables'
];
/**
* Determine whether the notification type has notifiables
*/
public function getHasNotifiablesAttribute(): bool
{
if (isset($this->notificationNotifiables) && count($this->notificationNotifiables) > 0) {
return true;
}
return false;
}
/**
* Get the notification channels for this model
*/
public function notificationChannels(): BelongsTo
{
return $this->belongsTo(NotificationChannel::class, 'notification_channel_id');
}
/**
* Get the model's notifiables
*/
public function notificationNotifiables(): MorphMany
{
return $this->morphMany(NotificationNotifiable::class, 'notifiable');
}
}
这是我的端点索引函数:/account/1/notification-preferences
/**
* Display a listing of the resource.
*/
public function index(User $account, Request $request)
{
try {
$channels = NotificationChannel::withWhereHas('notificationTypes', function ($query) {
$query->with([
'notificationNotifiables' => function ($query) {
$query->where('notifiable_type', User::class)->where('notifiable_id', Auth::id());
}
])->orderBy('display_order', 'asc');
})->orderBy('display_order', 'asc')->get();
if (! $channels || count($channels) <= 0) {
return new ApiSuccessResponse(null, [
'message' => 'No channels found.',
], 404);
}
return new ApiSuccessResponse($channels);
} catch (\Exception $e) {
return new ApiErrorResponse($e, [
'message' => 'Unable to load channels, please try again soon.',
]);
}
}
尽管此表中有一个条目,但为什么会为空?notificationNotifiables
答:
-6赞
Théodore
11/17/2023
#1
看起来该问题可能与查询中关系的急切加载有关。具体而言,withWhereHas 方法可能无法正确加载嵌套关系。此外,在 NotificationType 模型中,你将 belongsTo 用于 notificationChannels,但它应该是 hasMany,因为 NotificationType 可以有多个通道。
下面是使用 with 方法进行预先加载的索引函数的更新版本:
/**
* Display a listing of the resource.
*/
public function index(User $account, Request $request)
{
try {
$channels = NotificationChannel::with(['notificationTypes.notificationNotifiables' => function ($query) use ($account) {
$query->where('notifiable_type', User::class)->where('notifiable_id', $account->id);
}])
->orderBy('display_order', 'asc')
->get();
if (!$channels || $channels->isEmpty()) {
return new ApiSuccessResponse(null, [
'message' => 'No channels found.',
], 404);
}
return new ApiSuccessResponse($channels);
} catch (\Exception $e) {
return new ApiErrorResponse($e, [
'message' => 'Unable to load channels, please try again soon.',
]);
}
}
评论
3赞
Jesse
11/17/2023
stackoverflow.com/help/ai-policy
1赞
EJoshuaS - Stand with Ukraine
11/22/2023
这似乎是 ChatGPT 抄袭。
评论
Auth::id()
id
NotificationType
notificationChannels
notificationNotifiables
with
withWhereHas
hasMany