Home > OS >  can't find questions by category name in Laravel
can't find questions by category name in Laravel

Time:01-25

i am trying to retrieve questions based on the category witch they belong with this function inside my questions controller:

public function getByCategoryName($categoryName) {
        $category = Category::where('name', $categoryName)->first();
        return response($category->questions);

    }

the problem is that, even if $category its being correctly set, $questions is null and the browsers returns an empty response to my request

the tables are created like this:

Questions table:

        Schema::create('questions', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
            $table->string('title')->nullable(false);
            $table->string('content')->nullable(false);
            $table->integer('points')->default(0);
            $table->foreignId('user_id')
                ->constrained('users')
                ->onDelete('cascade');

            $table->string('category_name');
            $table->foreign('category_name')
                ->references('name')->on('categories')
                ->onDelete('cascade')
                ->onUpdate(null);

        });

categorie table:

Schema::create('categories', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
            $table->string('name')->nullable(false);
            $table->unique('name');
        });

I have the relatives relationship functions HasMany and BelongsTo seated inside the the models.

Question model:

public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }

Category model:

public function question() : HasMany {
        return $this->hasMany(Question::class);
    }

What am I doing wrong?

CodePudding user response:

As others have pointed out. It's better to use the primary ID key for efficient mapping. However, for education purposes it is possible and I will explain. Eloquent determines the foreign key name by examining the name of the relationship method and suffixing the method name with _id. So, in this case, Eloquent assumes that the Question model has a category_id column. However, since the foreign key on the Question model is not category_id, we must pass a custom key name as the second argument to the belongsTo method:

public function category()
{
    return $this->belongsTo(Category::class, 'foreign_key'); // If we do not pass this eloquent thinks the foreign key is 'category_id'
}

// We need to pass our custom foreign key
public function category()
{
    return $this->belongsTo(Category::class, 'category_name');
}

Eloquent assumes the parent model Category will be associated using its primary id. Since this is not our case we need to associate the parent model key to the 'name' column. So we need to pass a third argument to the belongsTo method specifying the parent tables custom key:

public function category()
{
    return $this->belongsTo(Category::class, 'category_name', 'name');
}

Your complete solution should look something like this.

// Question model
public function category()
{
    return $this->belongsTo(Category::class, 'category_name', 'name');
}

// Category model
public function questions()
{
    return $this->hasMany(Question::class, 'category_name', 'name');
}

CodePudding user response:

Change this :

    public function question() : HasMany {
        return $this->hasMany(Question::class);
    }

To this :

    public function questions() : HasMany {
        return $this->hasMany(Question::class, 'category_name');
    }
  • Related