В моем проекте есть модели продуктов и категорий. Товар относится к категории. Поскольку у продукта есть внешний ключ category_id, я мог бы легко отсортировать вывод следующим образом:

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

Но на самом деле я хотел отсортировать товары по названию категории, поэтому попробовал:

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

Но это ничего не дает. В качестве теста я вернул return Product::with('categories')->first();, и все нормально ...

Вот и красноречивые отношения.

Продукт

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');
    }
}

< Сильный > Категория :

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

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

И часть просмотра:

@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
12
Norgul 26 Апр 2016 в 09:30

4 ответа

Лучший ответ

Я не тестировал это, но думаю, это должно сработать

// Get all the products
$products = \App\Product::all();

// Add Closure function to the sortBy method, to sort by the name of the category
$products->sortBy(function($product) { 
  return $product->categories()->name;
});

Это также должно работать:

 $products = Product::with('categories')->get()
   ->sortBy(function($product) { 
       return $product->categories->name;
  })
7
geckob 26 Апр 2016 в 08:25

В laravel вы не можете выполнить заказ по связанной таблице без ручного присоединения к связанной таблице, что действительно очень неудобно, но этот пакет может сделать это за вас из коробки https://github.com/fico7489/laravel-eloquent-join

-2
fico7489 17 Дек 2017 в 18:26

Вы можете просто предоставить функцию для активной загрузки Eloquent, где вы можете обрабатывать запросы к связанной таблице.

$product = Product::with(['categories' => function ($q) {
  $q->orderBy('name', 'asc');
}])->find($productId);
0
Juha Vehnia 6 Сен 2020 в 03:19

Вы можете использовать join (), попробуйте код ниже

$query = new Product; //new object
//$query = Product::where('id','!=',0);
$query = $query->join('categories', 'categories.id','=','products.categories.id');
$query = $query->select('categories.name as cat_name','products.*');
$query = $query->orderBy('cat_name','asc');
$record = $query->get();
5
DsRaj 26 Апр 2016 в 07:20