Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel order by related table

I have Product and Category models in my project. Product belongs to Category. Since Product has foreign key category_id, I could easily sort the output like so:

$products = Product::orderBy('category_id', 'asc')->get();

But what I really wanted is to sort Products by Category name, so I tried:

$products = Product::with(['categories' => function($q){
            $q->orderBy('name', 'asc')->first();
        }]);

But that outputs nothing. As a test, I have returned return Product::with('categories')->first(); and it outputs fine...

Here are the Eloquent relations.

Product

class Product extends Model
{
    protected $fillable = [
        'name',
        'description',
        'price',
        'category_id',
    ];

    protected $hidden = [
        'created_at',
        'updated_at',
    ];

    public function categories()
    {
        return $this->belongsTo('\App\Category', 'category_id');
    }
}

Category:

class Category extends Model
{
    protected $fillable = [
        'name'
    ];

    public function products()
    {
        return $this->hasMany('\App\Product');
    }
}

And the view part:

@foreach ($products as $product)
                <tr>

                    <td>{!! $product->categories->name !!}</td>
                    <td>
                        @if(!empty($product->picture))
                            Yes
                        @else
                            No
                        @endif
                    </td>
                    <td>{!! $product->name !!}</td>
                    <td>{!! $product->description !!}</td>
                    <td>{!! $product->price !!}</td>
                    <td>
                        <a href="{{ url('/product/'.$product->id.'/edit') }}">
                            <i class="fa fa-fw fa-pencil text-warning"></i>
                        </a>
                        <a href="" data-href="{{route('product.destroyMe', $product->id)}}"
                           data-toggle="modal" data-target="#confirm-delete">
                            <i class="fa fa-fw fa-times text-danger"></i>
                        </a>
                    </td>
                </tr>
            @endforeach
like image 622
Norgul Avatar asked Apr 26 '16 06:04

Norgul


1 Answers

You can simply supply function to Eloquent eager loading where you can handle how the related table gets queried.

$product = Product::with(['categories' => function ($q) {
  $q->orderBy('name', 'asc');
}])->find($productId);
like image 84
Juha Vehnia Avatar answered Oct 10 '22 23:10

Juha Vehnia