Получение всех объектов из hasMany отношения и paginate
В моем приложении Laravel у меня есть страница со списком категорий. Когда пользователь нажимает на определенную подкатегорию, я хотел бы перечислить все продукты и использовать разбиение на страницы этого результата. Я уже перечисляю все продукты, относящиеся к этой подкатегории, теперь, с помощью идентификатора подкатегории:
public function subcategoryListing($slug){
$products = Subcategory::find($idofSubcat)->products;
return view('pages.subcategorylisting')
->with(array(
'products' => $products,
));
}
В этой структуре задействованы три класса: Категория, Подкатегория и Продукты. Они были объявлены следующим образом:
Категория
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Relation;
use App\Subcategory;
class Category extends Model
{
protected $table = 'category';
public $timestamps = false;
public function subCategory(){
return $this->hasMany('App\Subcategory', 'category_id');
}
}
категория
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Subcategory extends Model
{
protected $table = 'subcategory';
public $timestamps = false;
public function products(){
return $this->hasMany('App\Products');
}
}
Продукция
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Products extends Model
{
protected $table = 'products';
}
Для каждого класса модели у меня есть одна таблица с этой структурой:
Category
- id
- category_name
SubCategory
- id
- category_id
- subcategory_name
Products
- id
- subcategory_id
- product_title
- description
- price
Я хочу, чтобы разбивать результаты, полученные из запроса на моей странице. Есть ли лучший способ получить products
, связанный с subcategory
и разбивать на них страницы?
Ответы
Ответ 1
В Eloquent (Laravel ORM), когда вы вызываете отношение как свойство ($subCategory->products
), он возвращает связанный объект или коллекцию объектов в зависимости от типа отношения (принадлежит, имеет много,...). Вместо этого, если вы называете это функцией ($subCategory->products()
), вы получаете экземпляр QueryBuilder
.
Обратитесь к http://laravel.com/docs/5.1/eloquent-relationships#querying-relations в разделе Методы взаимодействия Vs. Динамические свойства для более подробной информации.
В любом случае, используя метод отношений, вы можете вызвать paginate()
для своей коллекции. Затем, имея в виду, вы можете немного изменить свой код, чтобы получить то, что вы хотите:
public function subcategoryListing($slug) {
// I'm supposing here that in somewhere before
// run the query, you set the value to $idofSubcat
// variable
$products = Subcategory::find($idofSubcat)->products()->paginate();
return view('pages.subcategorylisting')
->with(array(
'products' => $products,
));
}
Ответ 2
Я думаю, что создать две таблицы категорий не так правильно, лучше будет использовать следующий:
категории таблицы
id category_name parent_id(nullable)
и продукты
id category_id product_title description price
Более полезно, вы можете удалить одну модель подкатегории и сделать все в категории.
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
protected $table = 'category';
public $timestamps = false;
public function subCategory(){
return $this->belongsToMany('App\Category', 'categories', 'id', 'parent_id');
}
public function products(){
return $this->hasMany('App\Products');
}
}
и модель продуктов
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Products extends Model
{
protected $table = 'products';
public function category() {
return $this->belongsTo('App\Category')
}
}
тогда вы можете получить результат запроса
public function subcategoryListing($slug){
$products = Category::find($idofSubcat)->products;
return view('pages.subcategorylisting')
->withProducts($products); // it a magic))
}
Но, существующая одна некрасивая вещь. Вы действительно уверены, что продукты будут только в одной категории?)
Ответ 3
Я не мог понять некоторые из ваших первоначальных функций:
// $slug is not being used anywhere within the function
public function subcategoryListing($slug){
// $idOfSubcat isn't passed to this function so will throw an error
$products = Subcategory::find($idofSubcat)->products;
return view('pages.subcategorylisting')
->with(array(
'products' => $products,
));
}
Если все, что вы пытаетесь сделать, это paginate Products
, которые относятся к определенному subcategory_id
, если у вас есть subcategory_id
, тогда будет работать следующий код:
$products = Product::where('subcategory_id', $idofSubcat)->paginate();
Затем вы можете вернуть эту разбитую на страницу коллекцию к вашему представлению, как вы уже делаете:
return view('pages.subcategorylisting')
->with(compact('products'));