Laravel whereHas on Many-to-Many relationships
Asked Answered
L

2

7

I have two main tables with relationships many to many and a pivot table.

Model 'Type'

    public function attributes()
    {
        return $this->belongsToMany('App\Attribute', 'attribute_type');
    }

Model 'Attribute'

    public function types()
    {
        return $this->belongsToMany('App\Type', 'attribute_type');
    }

Pivot table 'attribute_type'

    Schema::create('attribute_type', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('type_id')->unsigned();
        $table->foreign('type_id')->references('id')->on('types');
        $table->integer('attribute_id')->unsigned();
        $table->foreign('attribute_id')->references('id')->on('attributes');
    });

I want to show 5 attributes in random order which belong to the types of id < 10.

$attributes = Attribute::whereHas('types', function ($query) {
            $query->where('id', '<', '10');
        })->orderByRaw("RAND()")->limit(5);

and for example

$attribute->id

gives me "Undefined property: Illuminate\Database\Eloquent\Builder::$id"

Leonardoleoncavallo answered 10/5, 2016 at 20:7 Comment(0)
P
12

All you have to do is execute query and get the collection with get() method like this:

$attributes = Attribute::whereHas('types', function ($query) {
        $query->where('id', '<', '10');
    })->orderByRaw("RAND()")->limit(5)
    ->get();

Now you are trying to iterate over the query builder which is giving you another query builder as a result of $attribute

Phyto answered 10/5, 2016 at 20:49 Comment(1)
also I changed where('id', '<', '10'); to where('type_id', '<', '10');Leonardoleoncavallo
C
5

You have 2 options:

$attributes = Attribute::whereHas('types', function ($query) {
            $query->where('types.id', '<', '10');
        })->orderByRaw("RAND()")->limit(5);

or

$attributes = Attribute::whereHas('types', function ($query) {
            $query->where('attribute_type.type_id', '<', '10');
        })->orderByRaw("RAND()")->limit(5);
Cofferdam answered 8/2, 2021 at 21:10 Comment(1)
While this might answer the question, if possible you should edit your answer to include a short explanation of how each of these statements answers the question. This helps to provide context and makes your answer more useful for future readers.Interconnect

© 2022 - 2024 — McMap. All rights reserved.