Laravel 10 morphMany无法检索可通知的模型

kcwpcxri  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(111)

我需要一些帮助与我的morphMany关系.我围绕允许用户通过不同的通知渠道获得各种类型的通知功能.这里是我的模型:

  • NotificationNotifiable-这定义了idnotifiable_typenotifiable_idnotification_type_id列,这是跟踪用户已启用并希望接收通知的所有类型的表。
  • NotificationChannel-只是一个简单的表格定义的渠道,例如:推,电子邮件,短信
  • NotificationType-定义通知类型及其对应的支持的notification_channel_id列的表,可能通过电子邮件进行的一般营销是一种类型。

我选择了NotificationNotifiable,因为我可能有其他型号也希望收到通知。
我可以从我的控制器(通知首选项)中检索数据,但是尽管有一个用户的条目,我在我的notificationNotifiable关系下没有看到这个条目,它是空的,这是我的模型:
1.型号: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);
    }
}

字符串
1.型号: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);
    }
}


1.型号: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在这个表中有一个条目,但仍然是空的?
x1c 0d1x的数据


fwzugrvs

fwzugrvs1#

看起来问题可能与查询中关系的即时加载有关。具体而言,withWhereHas方法可能无法正确加载嵌套关系。此外,在NotificationType模型中,您正在为notificationChannels使用HassTo,但它应该是hasMany,因为NotificationType可以有多个通道。
下面是index函数的更新版本,它使用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.',
        ]);
    }
}

字符串

相关问题