【问题标题】:No query results for model [App\Models\Match]模型 [App\Models\Match] 没有查询结果
【发布时间】:2018-03-16 19:51:45
【问题描述】:

我正在使用 Laravel 构建一个 API,并希望使用 Laravel 通知系统发送推送通知。我有一个匹配模型(基本上是一个帖子),另一个用户可以喜欢这个匹配。当比赛被点赞时,帖子的创建者将收到推送通知。就像 Instagram、Facebook 等一样。

推送通知通常不会发送给用户。我安装了 Laravel Horizo​​n 看看是否有错误。有时通知已发送,有时未发送。使用完全相同的数据:

通知有时会因为完全相同的数据(相同的用户,相同的匹配)而失败。

报错如下:

Illuminate\Database\Eloquent\ModelNotFoundException: 没有查询结果 对于模型 [App\Models\Match] 118 in /home/forge/owowgolf.com/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:312

我确定匹配且用户存在于数据库中,我已在发送通知之前验证了这一点。有人知道出了什么问题吗?我在网上能找到的一切都是人们在将通知发送到队列之前没有保存他们的模型。但是,如果模型不存在,甚至不会到达代码将通知发送到队列的那一行。由于路由/控制器中的隐式绑定。

控制器方法:

/**
 * Like a match.
 *
 * @param  \App\Models\Match  $match
 * @return \Illuminate\Http\JsonResponse
 */
public function show(Match $match)
{
    $match->like();

    $players = $match->players()->where('user_id', '!=', currentUser()->id)->get();

    foreach ($players as $user) {
        $user->notify(new NewLikeOnPost($match, currentUser()));
    }

    return ok();
}

通知:

<?php

namespace App\Notifications;

use App\Models\Match;
use App\Models\User;
use Illuminate\Bus\Queueable;
use NotificationChannels\Apn\ApnChannel;
use NotificationChannels\Apn\ApnMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;

class NewLikeOnPost extends Notification implements ShouldQueue
{
    use Queueable;

    /**
     * The match instance.
     *
     * @var \App\Models\Match
     */
    private $match;

    /**
     * The user instance.
     *
     * @var \App\Models\User
     */
    private $user;

    /**
     * Create a new notification instance.
     *
     * @param  \App\Models\Match  $match
     * @param  \App\Models\User  $user
     */
    public function __construct(Match $match, User $user)
    {
        $this->user = $user;
        $this->match = $match;

        $this->onQueue('high');
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  \App\Models\User  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        if ($notifiable->wantsPushNotification($this)) {
            return ['database', ApnChannel::class];
        }

        return ['database'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  \App\Models\User  $notifiable
     * @return \NotificationChannels\Apn\ApnMessage
     */
    public function toApn($notifiable)
    {
        return ApnMessage::create()
            ->badge($notifiable->unreadNotifications()->count())
            ->sound('success')
            ->body($this->user->username . ' flagged your match.');
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            'user_id' => $this->user->id,
            'body' => "<flag>Flagged</flag> your match.",
            'link' => route('matches.show', $this->match),
            'match_id' => $this->match->id,
        ];
    }

    /**
     * Get the match attribute.
     *
     * @return \App\Models\Match
     */
    public function getMatch()
    {
        return $this->match;
    }
}

【问题讨论】:

  • 显示通知文件的代码。
  • 添加NewLikeOnPost通知类的代码。
  • 我不确定,但是您尝试访问作业中的会话数据或您在队列中处理的任何函数或对象的任何地方都在使用会话?
  • 无论是什么原因,您都可能面临 postgresql 行锁(主要是过度使用 currentUser() 方法)。检查这篇文章它可能对你有帮助:stackoverflow.com/questions/1063043/…
  • 这与使用相同队列系统的同一服务器上的多个环境有关。暂存的事件/作业正在生产队列中执行。

标签: php laravel laravel-5 queue laravel-horizon


【解决方案1】:

检查您的 .env 以确保您确实使用了 REDIS

BROADCAST_DRIVER=redis
CACHE_DRIVER=redis
SESSION_DRIVER=redis
SESSION_LIFETIME=120
QUEUE_DRIVER=redis

然后清除缓存(php artisan cache:clear , php artisan view:clear),这应该可以解决问题

编辑

我有类似的问题,但现在我只使用 Docker,并且在我必须检查缓存的配置文件、错误的文件/文件夹权限等之前(REDIS 仅用于广播,其他是标准的)。我开始只使用 redis - 这对我来说更容易、更快、更易于调试!与 Docker 一起使用确实有助于不使用混乱的 nginx/apache/php/redis/ ...

【讨论】:

  • 没修好:(
  • 这不是答案
【解决方案2】:

这可能是因为 $user 不是 User 模型的对象,它是 Match 模型的对象。您需要执行 User::findorfail 或 User::firstOrFail 然后通知用户。

public function show(Match $match)
{
$match->like();

$players = $match->players()->where('user_id', '!=', currentUser()->id)->get();

foreach ($players as $user) {
    $someUser = User::findOrFail($user->user_id);
    $someUser->notify(new NewLikeOnPost($match, currentUser()));
}

return ok();

}

除非在 Match 模型中使用了 notify 特征。或者您可以使用预先加载,这将花费更少的查询!

【讨论】:

    【解决方案3】:

    这不是一个完整的解决方案,但它会降低您将来遇到此错误的机会。

    不要将整个Match 模型传递到作业中,而是只传递模型的id。然后,您可以在构造函数中获取该模型。

    /**
     * Like a match.
     *
     * @param  \App\Models\Match  $match
     * @return \Illuminate\Http\JsonResponse
     */
    public function show(Match $match)
    {
        $match->like();
    
        $players = $match->players()->where('user_id', '!=', currentUser()->id)->get();
    
        foreach ($players as $user) {
            $user->notify(new NewLikeOnPost($match->id, currentUser()->id));
        }
    
        return ok();
    }
    

    通知:

    class NewLikeOnPost extends Notification implements ShouldQueue
    {
        use Queueable;
    
        private const QUEUE_NAME = 'high';
    
        /**
         * The match instance.
         *
         * @var \App\Models\Match
         */
        private $match;
    
        /**
         * The user instance.
         *
         * @var \App\Models\User
         */
        private $user;
    
        /**
         * Create a new notification instance.
         *
         * @param  int $match
         * @param  int $user
         */
        public function __construct(int $matchId, int $userId)
        {
            $this->user = User::query()->where('id', $userId)->firstOrFail();
            $this->match = Match::query()->where('id', $matchId)->firstOrFail();
    
            $this->onQueue(self::QUEUE_NAME);
        }
    
        // Rest of the class is still the same...
    }
    

    你可以使用SerializesModels trait,但是当你给一个排队的作业添加一个延迟时它就不能很好地工作了。这是因为它会尝试在__wakeup() 上重新加载模型,有时会找不到类。

    希望这会有所帮助:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-12
      • 1970-01-01
      • 1970-01-01
      • 2019-12-04
      • 2015-09-23
      • 1970-01-01
      • 2014-12-26
      相关资源
      最近更新 更多