mardi 22 janvier 2019

Laravel - Query scope in another model doesn't work

There is a model named Message as follow (the user_id is sender of the message):

class Message extends Model
{
    protected $fillable = ['title', 'body', 'visible', 'message_type_id', 'user_id'];
    public function user()
    {
        return $this->belongsTo('Modules\User\Entities\User', 'user_id');
    }

    public function user_messages() // recipients
    {
        return $this->hasMany('Modules\Message\Entities\MessageUser', 'message_id');
    }

    public function scopeReceiver($query, $user_id)
    {
        return $query->whereHas('user_messages', function($q) use ($user_id){
            $q->receiver($user_id);
        });
    }

    public function scopeUnread($query)
    {
        return $query->whereHas('user_messages', function ($q){
            $q->unread();
        });
    }

    public function scopeAuthor($query, $user_id)
    {
        return $query->where("user_id", $user_id);
    }

Since a message maybe sent to multiple users, I created a model named MessageUser which contains list of recipients of every message. it is as follows (the read column is boolean):

class MessageUser extends Model
{
    protected $fillable = ['message_id', 'user_id', 'read'];
    protected $table = "message_user";

    public function user()
    {
        return $this->belongsTo('Modules\User\Entities\User', 'user_id');
    }

    public function scopeReceiver($query, $user_id)
    {
        return $query->where('user_id', $user_id);
    }

    public function scopeUnread($query)
    {
        return $query->where('read', 0);
    }

    public function scopeTheMessage($query, $message_id)
    {
        return $query->where('message_id', $message_id);
    }

    public function message()
    {
        return $this->belongsTo('Modules\Message\Entities\Message', 'message_id');
    }
}

I need to get the unread messages sent from a specific user to the current user. This is the code I wrote which is not working

public function unreadMessages($user_id)
{
    $author = $user_id;
    $recipient = $this->user->id;
    dd(Message::author($author)->receiver($recipient)->unread()->get());
    $count = Message::author($author)->receiver($recipient)->unread()->count();
    return $count;
}

The result of dd is wrong. It successfully returns messages written by an author to current user, but it has problem with unread messages. Here is the problem:

enter image description here

the current user id is 2, and rows shown in rectangle are messages sent by a user to current user. The query

Message::author($author)->receiver($recipient)->get();

returns 4 shown messages which is right, but the query

Message::author($author)->receiver($recipient)->unread()->get();

return records with id 6, 17. The record with id 17 is right cause it is actually unread but record with id 6 is wrong. From what I observed I findout that it returns the wrong result because record with id 7 is unread! message_id 28 in records 6,7,8 is sent to three users. Because there is at least one user who didn't read it, so always returns that message as unread, no matter who the recipient is.



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire