skip to Main Content

I’m trying to return all Threads that a given User has participated in.

The endpoint accepts a userId and supposed to return a collection of thread models.

However, I keep getting this error when executing the controller action. It’s looking for a message_id column but I don’t have that defined on the thread table or on any table, for that matter – making this a weird error.

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'thread.message_id' in 'where 
clause' (SQL: select * from `thread` where `thread`.`message_id` = 2 and 
`thread`.`message_id` is not null)"

I believe there might be something off with how I’m linking the tables but I’m not entirely sure. I’d assume the message table’s column thread_id should reference the id column on the thread table which’s what I thought I was doing in the message migration below.

What am I doing wrong and how can I fix this?

Here’s users migration:

Schema::create('users', function (Blueprint $table) {
        $table->id('id');
        $table->string('email')->unique();
        $table->string('full_name');
        $table->string('password');
});

Here’s thread migration:

Schema::create('thread', function (Blueprint $table) {
        $table->id();
        $table->string('title');
});

Here’s message migration:

Schema::create('message', function (Blueprint $table) {
        $table->id();
        $table->unsignedBigInteger('user_id');
        $table->unsignedBigInteger('thread_id');
        $table->string('body');
        $table->foreign('user_id')
            ->references('id')
            ->on('users')
            ->onDelete('cascade');
        $table->foreign('thread_id')
            ->references('id')
            ->on('thread')
            ->onDelete('cascade');
});

controller action:

public function getUserThreads($userId) {
    $userParticipatedThreads = Message::findOrFail($userId);
    return $userParticipatedThreads->thread;
}

message model:

public function thread() {
    return $this->hasMany(Thread::class);
}

endpoint:

[GET] http://127.0.0.1:8000/api/getUserThreads/2

Route::get('getUserThreads/{userId}', [ThreadController::class, 'getUserThreads']);

2

Answers


  1. Your thread relationship on your Message class is looking for the message_id, since that’s the default way the hasMany relationship works. You’ll need to override the column that it’s basing the relationship off of.

    public function thread() {
        return $this->hasMany(Thread::class, 'id', 'thread_id');
    }
    

    However, since it looks like the message belongs to one single thread (each message has a thread_id), then you actually want belongsTo instead

    public function thread() {
        return $this->belongsTo(Thread::class);
    }
    
    Login or Signup to reply.
  2. To answer the question;

    Why am I getting a column not found error when trying to return a
    collection model based on user ID?

    Because your thread table doesn’t have a message_id field defined on it.

    Schema::create('thread', function (Blueprint $table) {
            $table->id();
            $table->string('title');
    });
    

    A Message belongs to a Thread but you seem to have that relationship inverted.

    On your Thread model, define a relationship to the Message model:

    public function messages()
    {
        return $this->hasMany(Message::class);
    }
    

    Then you can query for the existance of some message by user:

    $messages = Thread::whereHas('messages', function ($query) use ($userId) {
        $query->where('user_id', $userId);
    })->get();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search