Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 26.01.2015 02:38:08

Выборка из двух таблиц ORM

Всем доброго времени суток.
Необходимо сделать в одном запросе выборку из двух таблиц.

1) есть таблица товара Products
id | category_id | name | price
в ней есть колонка цена - price (что логично общее для всех продуктов)


2) есть таблица атрибутов Attributes
id | category_id | name

в ней хранятся названия уникальных атрибуты для товаров
как вариант:
аккумуляторы - емкость
жесткий диск - объем

3) есть таблица принадлежности атрибута продукту Product_Attributes
id | product_id | attribute_id | value

как понятно из названия тут соответствия продукта атрибуту
полюс еще колонка value - тут собственно сами данные атрибута

Собственно проблема в том, что необходимо сделать выборку из двух таблиц:
по price (от и до) и по value (от и до) скажем для "жесткого диска"

В Products прописана связь одинКоМногим

public function productattributes() {
        return $this->hasMany('ProductAttribute');
}

В Product_Attributes прописана связь многиеКОдному

public function product() {
        return $this->belongsTo('Product');
    }

Подскажите как правильно организовать запрос.

Пробовал в начале так:

$products = Product::orderBy('updated_at', 'DESC')
->where('category_id', '=', $id)
->whereBetween('price', [$priceMin, $priceMax])
->with('productattributes')
->whereBetween('value', [$sizeMin, $sizeMax])
->get();

Но (как всем понятно) это не сработало.
Я понимаю, что что-то не понимаю, в что понять не могу. (((((

За ранее спасибо всем.

Не в сети

#2 26.01.2015 09:10:42

Re: Выборка из двух таблиц ORM

По-моему, здесь проблема не в запросе, а скорее в неправильно спроектированных таблицах.

Не в сети

#3 26.01.2015 11:18:54

Re: Выборка из двух таблиц ORM

Afatar пишет:

По-моему, здесь проблема не в запросе, а скорее в неправильно спроектированных таблицах.

Возможно Вы правы. Как Вы считаете, что нужно именно сделать?
И как все же реализовать запрос?

Спасибо )

Не в сети

#4 26.01.2015 12:15:18

Re: Выборка из двух таблиц ORM

Afatar пишет:

По-моему, здесь проблема не в запросе, а скорее в неправильно спроектированных таблицах.

По моему Вы правы. По определению Entity–attribute–value, Value должен быть отдельной таблицей.
Но всеравно, как тогда организовывать запрос-выборку?

Не в сети

#5 26.01.2015 16:48:25

Re: Выборка из двух таблиц ORM

Нашел решение (хотя и не самое изящное).
По поводу таблиц, думаю все же правильная структура выбрана. Скорее всего не хватает некой связующей таблицы как вешнего ключа.
Если кто поправит или подскажет - спасибо огромное.
Эта мой первый проект на laravel и грабли, думаю не избеджны )))

Не в сети

#6 27.01.2015 04:46:36

Re: Выборка из двух таблиц ORM

Для каждого товара атрибут только один? Т.е. если это жесткий диск, то он имеет только объем? Или атрибутов для каждого товара буде много? Объем, размер, скорость и.т.д.?

Не в сети

#7 27.01.2015 14:48:29

Re: Выборка из двух таблиц ORM

Afatar пишет:

Для каждого товара атрибут только один? Т.е. если это жесткий диск, то он имеет только объем? Или атрибутов для каждого товара буде много? Объем, размер, скорость и.т.д.?

Ну, на самом деле атрибутов много)))
И, в зависимости от категории, будут выводится разные (как количественно, так и качественно).
Как пример - вывод всех (почти всех ))) атрибутов:
Общее представление таблиц с содержимым:
(таблица categories)
id | name
1  | Жесткие диски
2  | Аккумуляторы

(таблица protucts)
id | category_id | name | price
1  | 1                | WD    | 100
2  | 1                | Sams | 200
3  | 2                | Super| 20

(таблица attributes)
id | category_id | name
1  | 1                | Объём
2  | 1                | Тип
3  | 1                | Скорость
4  | 2                | Ёмкость
5  | 2                | Тип

(таблица protuct_attributes)
id | protuct_id | attribute_id | value
1  | 1              | 1                | 1Tb
2  | 1              | 2                | sata II
3  | 1              | 3                | 7 200
4  | 2              | 1                | 2Tb
5  | 2              | 2                | sata III
6  | 2              | 3                | 10 000
7  | 3              | 4                | 2800
8  | 4              | 5                | AA

Вот, как то так))

Задача заключается в том, что бы одним запросом отсортировать и вывести данные по продукту
как по цене (таб. products) , так и скорости (таб. attributes, protuct_attributes ) (для жестких дисков, как вариант)
Но создается такое впечатление, что в laravel, средствами ORM, подобные запросы в принципе не возможны.
Тут еще не указанно одна таблица product_images - там хранятся ссылки на изображения продуктов.
Вот почему принципиально важно решить задачу именно с использованием ORM.

Буду признателен за правки и любую конструктивную критику )))))

Не в сети

#8 28.01.2015 03:16:24

Re: Выборка из двух таблиц ORM

Через Eloquent скорее все не получится. Через ОРМ  работает.
Это запрос всех товаров со всеми атрибутами и значениями атрибутов, с названием категории с сортировкой по цене.

class MainController extends BaseController {

	public function index()
	{		
		$data=DB::table('products')
		->leftJoin('categories','products.category_id','=','categories.id')
		->leftJoin('atributes','atributes.category_id','=','categories.id')
		->leftJoin('value','value.atribute_id','=','atributes.id')
		->select('products.name as name','products.price as price','categories.name as category','atributes.name as atribute','value.value')
		->orderBy('products.price')
		->get();
		
		return View::make('index',['data'=>$data]);
	}

}
Во вьюшке делаешь разбор

@foreach($data as $item)
{{$item->price}}
{{$item->name}}
....
{{$item->value}}

Не в сети

#9 28.01.2015 11:23:42

Re: Выборка из двух таблиц ORM

Afatar пишет:

Через Eloquent скорее все не получится. Через ОРМ  работает.
Это запрос всех товаров со всеми атрибутами и значениями атрибутов, с названием категории с сортировкой по цене.

class MainController extends BaseController {

	public function index()
	{		
		$data=DB::table('products')
		->leftJoin('categories','products.category_id','=','categories.id')
		->leftJoin('atributes','atributes.category_id','=','categories.id')
		->leftJoin('value','value.atribute_id','=','atributes.id')
		->select('products.name as name','products.price as price','categories.name as category','atributes.name as atribute','value.value')
		->orderBy('products.price')
		->get();
		
		return View::make('index',['data'=>$data]);
	}

}
Во вьюшке делаешь разбор

@foreach($data as $item)
{{$item->price}}
{{$item->name}}
....
{{$item->value}}

Спасибо ))))))
Попробую так.

Не в сети

#10 28.01.2015 15:38:03

HN

Re: Выборка из двух таблиц ORM

Afatar пишет:

Через Eloquent скорее все не получится. Через ОРМ  работает.
Это запрос всех товаров со всеми атрибутами и значениями атрибутов, с названием категории с сортировкой по цене.

class MainController extends BaseController {

	public function index()
	{		
		$data=DB::table('products')
		->leftJoin('categories','products.category_id','=','categories.id')
		->leftJoin('atributes','atributes.category_id','=','categories.id')
		->leftJoin('value','value.atribute_id','=','atributes.id')
		->select('products.name as name','products.price as price','categories.name as category','atributes.name as atribute','value.value')
		->orderBy('products.price')
		->get();
		
		return View::make('index',['data'=>$data]);
	}

}
Во вьюшке делаешь разбор

@foreach($data as $item)
{{$item->price}}
{{$item->name}}
....
{{$item->value}}

Тут есть один недостаток - не учтена обработка whereBetween  для многих атрибутов

#11 29.01.2015 02:05:27

Re: Выборка из двух таблиц ORM

Пример выборки по цене от 1000 до 3000

$data=DB::table('products')->whereBetween('price',[1000, 3000])
		->leftJoin('categories','products.category_id','=','categories.id')
		->leftJoin('atributes','atributes.category_id','=','categories.id')
		->leftJoin('value','value.atribute_id','=','atributes.id')
		->select('products.name as name','products.price as price','categories.name as category','atributes.name as atribute','value.value')
		->orderBy('products.price')
		->get();

Не в сети

#12 29.01.2015 11:36:50

Re: Выборка из двух таблиц ORM

Afatar пишет:

Пример выборки по цене от 1000 до 3000

$data=DB::table('products')->whereBetween('price',[1000, 3000])
		->leftJoin('categories','products.category_id','=','categories.id')
		->leftJoin('atributes','atributes.category_id','=','categories.id')
		->leftJoin('value','value.atribute_id','=','atributes.id')
		->select('products.name as name','products.price as price','categories.name as category','atributes.name as atribute','value.value')
		->orderBy('products.price')
		->get();

Спасибо) Ну это просто, так как price находится в главной (protuct) таблице, а вот атрибуты в отдельной (product_attributs) и к одному продукту могут относиться несколько атрибутов. И отличить атрибуты можно только по product_id (как привязка к продукту) и attribute_id (как как привязка к идентификатору атрибута).
Т.е. у продукта может быть несколько атрибутов с одинаковыми value и отличатся только по id атрибута.
А значит нудно фильтровать value по соответствующему attribute_id который принадлежит protuct_id.
О как завернул))

Пока однозначного решения не нашел.

Не в сети

Подвал раздела