Виджет, main.php или как не нужно делать?!

Обсуждаем, как правильно строить приложения
Trampampam
Сообщения: 19
Зарегистрирован: 2015.12.07, 20:01

Виджет, main.php или как не нужно делать?!

Сообщение Trampampam »

Всем здравствуйте.

Есть желание вывести пять самых популярных и пять самых новых статей из категории. Код для одного экшена получился таким:

public function actionCategory()
{
$popular = DBContent::find()
->where ('catid = 79') / АйДи категории /
->orderBy('hits DESC') / сортировка по просмотрам /
->limit(5)
->all();

$news = DBContent::find()
->where ('catid = 79')
->orderBy('created DESC') / сортировка по дате создания /
->limit(5)
->all();

return $this->render('category', ['popular' => $popular,'news'=>$news]);
}

Во вью выводится через foreach.

Категорий на сайте шесть штук. Нужно создавать подобный экшн на каждую категорию или это не путь Джедая и нужно делать выборку по айди категории с запрошенной пользователем страницы одним экшеном и айди/алиас категории брать из урл?! База данных - наследствие джумлы с урл вида /категория/айди+алиас страницы.

Оправдан ли двойной DBContent::find() в одном экшене?! Или все можно как-то получить за одно обращение к БД?!
---------------------

Вторая часть вопроса: Если это все делается через виджет в main.php, то нужно ли делать по виджету на категорию или можно как-то запихать всё в один с выборкой в зависимости от запрошенной страницы?! Если да, то как это делается ?!

-------------
Главный момент! Нужен совет не как будет работать, а как потом не будет стыдно показать сведущим людям.

зы абсолютный новичок. Разрозненные данные можно найти на форуме/интернете, но есть опасения уйти в не самые лучшие практики написания кода. Да и не особо понятно, когда по кусочку.

Спасибо за внимание.
Аватара пользователя
SiZE
Сообщения: 2813
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Виджет, main.php или как не нужно делать?!

Сообщение SiZE »

Щас придет zelenin и погонит тебя ссаными тряпками. :D

Твой вопрос вобщем-то не имеет однозначного ответа. Пробовал читать гайд? http://www.yiiframework.com/doc-2.0/guide-index.html
Аватара пользователя
SiZE
Сообщения: 2813
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Виджет, main.php или как не нужно делать?!

Сообщение SiZE »

Запросы как минимум надо убрать в модель. Можно почитать вот эту тему http://www.yiiframework.ru/forum/viewto ... 19&t=33472, возможно придет просветление
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Виджет, main.php или как не нужно делать?!

Сообщение zelenin »

SiZE писал(а):Запросы как минимум надо убрать в модель. Можно почитать вот эту тему http://www.yiiframework.ru/forum/viewto ... 19&t=33472, возможно придет просветление
нахрена запросы-то в модель? запросы должны быть инкапсулированы в сервис.

Но в данном случае, как я понимаю, должны применять виджеты. А catId передавать в параметры виджета.
Trampampam
Сообщения: 19
Зарегистрирован: 2015.12.07, 20:01

Re: Виджет, main.php или как не нужно делать?!

Сообщение Trampampam »

To SiZE: гайд читал и читаю. Проблема усугубляется тем, что еще не совсем владею самой терминологией. С запросами в модели не согласен. К слову, есть гайд и на русском.
To zelenin: Спасибо. Попробую разобраться.

Остался вопрос: Оправдан ли двойной DBContent::find() в одном экшене?! Или все можно как-то получить за одно обращение к БД?! / код выше/
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Виджет, main.php или как не нужно делать?!

Сообщение zelenin »

Trampampam писал(а):To SiZE: гайд читал и читаю. Проблема усугубляется тем, что еще не совсем владею самой терминологией. С запросами в модели не согласен. К слову, есть гайд и на русском.
To zelenin: Спасибо. Попробую разобраться.

Остался вопрос: Оправдан ли двойной DBContent::find() в одном экшене?! Или все можно как-то получить за одно обращение к БД?! / код выше/
вы сможете это вытащить за один запрос из БД? Напишите голый запрос.
Trampampam
Сообщения: 19
Зарегистрирован: 2015.12.07, 20:01

Re: Виджет, main.php или как не нужно делать?!

Сообщение Trampampam »

zelenin писал(а):
Trampampam писал(а):To SiZE: гайд читал и читаю. Проблема усугубляется тем, что еще не совсем владею самой терминологией. С запросами в модели не согласен. К слову, есть гайд и на русском.
To zelenin: Спасибо. Попробую разобраться.

Остался вопрос: Оправдан ли двойной DBContent::find() в одном экшене?! Или все можно как-то получить за одно обращение к БД?! / код выше/
вы сможете это вытащить за один запрос из БД? Напишите голый запрос.
Я-нет. Потому и вопрошаю, это в принципе возможно или нет. Мне думается, что нет. Есть мысль выполнить запрос и записать в массив и массив подвергнуть сперва одной сортировке с записью результата в другой массив (ну или сделать копию исходного после сортировки), потом вторая сортировка. В итоге, есть два массива одного и того же, но сортированные по разному для дальнейшей работы. Хз насколько это возможно и насколько правильно.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Виджет, main.php или как не нужно делать?!

Сообщение zelenin »

Trampampam писал(а):
zelenin писал(а):
Trampampam писал(а):To SiZE: гайд читал и читаю. Проблема усугубляется тем, что еще не совсем владею самой терминологией. С запросами в модели не согласен. К слову, есть гайд и на русском.
To zelenin: Спасибо. Попробую разобраться.

Остался вопрос: Оправдан ли двойной DBContent::find() в одном экшене?! Или все можно как-то получить за одно обращение к БД?! / код выше/
вы сможете это вытащить за один запрос из БД? Напишите голый запрос.
Я-нет. Потому и вопрошаю, это в принципе возможно или нет. Мне думается, что нет. Есть мысль выполнить запрос и записать в массив и массив подвергнуть сперва одной сортировке с записью результата в другой массив (ну или сделать копию исходного после сортировки), потом вторая сортировка. В итоге, есть два массива одного и того же, но сортированные по разному для дальнейшей работы. Хз насколько это возможно и насколько правильно.
я не про yii. я про чистый mysql запрос. Если вы его не можете написать, то о чем мы говорим?
Trampampam
Сообщения: 19
Зарегистрирован: 2015.12.07, 20:01

Re: Виджет, main.php или как не нужно делать?!

Сообщение Trampampam »

zelenin писал(а):
Trampampam писал(а):
zelenin писал(а): вы сможете это вытащить за один запрос из БД? Напишите голый запрос.
Я-нет. Потому и вопрошаю, это в принципе возможно или нет. Мне думается, что нет. Есть мысль выполнить запрос и записать в массив и массив подвергнуть сперва одной сортировке с записью результата в другой массив (ну или сделать копию исходного после сортировки), потом вторая сортировка. В итоге, есть два массива одного и того же, но сортированные по разному для дальнейшей работы. Хз насколько это возможно и насколько правильно.
я не про yii. я про чистый mysql запрос. Если вы его не можете написать, то о чем мы говорим?
Хороший способ проверки. Не подумал. Спасибо.
Аватара пользователя
maleks
Сообщения: 1985
Зарегистрирован: 2012.12.26, 12:56

Re: Виджет, main.php или как не нужно делать?!

Сообщение maleks »

zelenin писал(а):
SiZE писал(а):Запросы как минимум надо убрать в модель. Можно почитать вот эту тему http://www.yiiframework.ru/forum/viewto ... 19&t=33472, возможно придет просветление
нахрена запросы-то в модель? запросы должны быть инкапсулированы в сервис.
А можно пример такого сервиса? Где хранить, какой тип класса, запросы в статических методах?
Yii2 universal module sceleton - for basic and advanced templates
Аватара пользователя
ksetrin
Сообщения: 81
Зарегистрирован: 2015.03.06, 10:00
Контактная информация:

Re: Виджет, main.php или как не нужно делать?!

Сообщение ksetrin »

maleks писал(а):
zelenin писал(а):
SiZE писал(а):Запросы как минимум надо убрать в модель. Можно почитать вот эту тему http://www.yiiframework.ru/forum/viewto ... 19&t=33472, возможно придет просветление
нахрена запросы-то в модель? запросы должны быть инкапсулированы в сервис.
А можно пример такого сервиса? Где хранить, какой тип класса, запросы в статических методах?
Если собрался слушать zelenin про сервисы, то лучше сразу переходи на sf2.
Он конечно что-нибудь ответить тебе про сервисы, но лучше сам почитай, например, тут http://symfony.com/doc/current/book/ser ... ainer.html
Большинство так называемых "запросов" можно уместить в "магические методы". Сервисы просто для свалки запросов использовать - я бы не стал. Ибо лишняя прослойка должна быть всегда оправдана.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Виджет, main.php или как не нужно делать?!

Сообщение zelenin »

ksetrin писал(а):Если собрался слушать zelenin про сервисы, то лучше сразу переходи на sf2.
вообще не связанные вещи
ksetrin писал(а):Он конечно что-нибудь ответить тебе про сервисы, но лучше сам почитай, например, тут http://symfony.com/doc/current/book/ser ... ainer.html
аналогично. В контексте симфони сервисы - аналоги yii-компонентов, регистрируемых в конфиге.
ksetrin писал(а):Большинство так называемых "запросов" можно уместить в "магические методы".
какие еще магические методы?
ksetrin писал(а):Сервисы просто для свалки запросов использовать - я бы не стал.
сервисы - это не свалка запросов, а инкапсуляция однородной функциональности с целью не превращать в свалку модель, которая не предназначена для этого.
ksetrin писал(а):Ибо лишняя прослойка должна быть всегда оправдана.
и поэтому сервисный слой - самое разумное решение.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Виджет, main.php или как не нужно делать?!

Сообщение zelenin »

пример:

Код: Выделить всё

public function actionCategory()
{
$dbContentFetcher = new DbContentFetcher;

$popular = $dbContentFetcher->getPopular(79, 5);
$news = $dbContentFetcher->getNews(79, 5);

return $this->render('category', ['popular' => $popular,'news'=>$news]);
}
 
это позволит сократить код в экшне (тонкий контроллер), вынести прямые запросы в БД в отдельный класс (S в слове SOLID), поднимет ваш опыт в глазах других (К в слове КРУТОЙ).

Статические и магические методы - зло, и их надо избегать.
Аватара пользователя
maleks
Сообщения: 1985
Зарегистрирован: 2012.12.26, 12:56

Re: Виджет, main.php или как не нужно делать?!

Сообщение maleks »

т.е. просто вспомогательные объекты.
а в контексте модуля в какой namespace их лучше размещать? в подобное?: modulenamespace\services\...
Yii2 universal module sceleton - for basic and advanced templates
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Виджет, main.php или как не нужно делать?!

Сообщение zelenin »

maleks писал(а):т.е. просто вспомогательные объекты.
а в контексте модуля в какой namespace их лучше размещать? в подобное?: modulenamespace\services\...
ну например. Варианты есть в зависимости от вашего взгляда на роль этого сервиса.

И еще поясню почему объекты, а не статические методы (про зло статики в целом уже сказал выше). D из SOLID - dependency injection. Создавая объект мы должны передать в конструктор зависимость сервиса.

Код: Выделить всё

$dbContentFetcher = new DbContentFetcher(Yii::$app->getDb());
 
типа того. но в нашем случае ::find() уже сам внутри дергает стандартное db-соединение, поэтому можно обойтись без зависимостей.

Вообще пример такого сервиса - это вариация на тему "репозиторий". Но сервисы могут быть более сложными вещами. Например инкапсулировать в себе $model->load(..), $model->save(), обработку связанных моделей итд - какой-то пакет связанных действий.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Виджет, main.php или как не нужно делать?!

Сообщение zelenin »

ksetrin писал(а):
zelenin писал(а): какие еще магические методы?
http://php.net/manual/en/language.oop5.magic.php
значит я вас правильно понял, но не понял куда вы их хотите запихнуть в рамках данной темы. Плюс магию нужно использовать там, где без нее обойтись нельзя.
andrei.obuhovski
Сообщения: 610
Зарегистрирован: 2015.07.16, 10:50

Re: Виджет, main.php или как не нужно делать?!

Сообщение andrei.obuhovski »

ksetrin писал(а): Если собрался слушать zelenin про сервисы, то лучше сразу переходи на sf2.
Он конечно что-нибудь ответить тебе про сервисы, но лучше сам почитай, например, тут http://symfony.com/doc/current/book/ser ... ainer.html
Это видимо аналог Service Locator в yii.
https://github.com/yiisoft/yii2/blob/ma ... locator.md
ksetrin писал(а): Большинство так называемых "запросов" можно уместить в "магические методы". Сервисы просто для свалки запросов использовать - я бы не стал. Ибо лишняя прослойка должна быть всегда оправдана.
Сервисы - это прослойка логики, т.к. ее в контроллере не должно быть. Но и в сущностях ее не должно быть, т.к. логика может использовать несколько сущностей.
Аналог ModelForm и ModelSearch. Только ModelForm и ModelSearch конкретно для форм и поиска используются. Но логика разная бывает, поэтому ModelService.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Виджет, main.php или как не нужно делать?!

Сообщение zelenin »

andrei.obuhovski писал(а):
ksetrin писал(а): Если собрался слушать zelenin про сервисы, то лучше сразу переходи на sf2.
Он конечно что-нибудь ответить тебе про сервисы, но лучше сам почитай, например, тут http://symfony.com/doc/current/book/ser ... ainer.html
Это видимо аналог Service Locator в yii.
https://github.com/yiisoft/yii2/blob/ma ... locator.md
так и есть. но к сервисам, обсуждаемым в ветке имеет лишь отдаленное отношение.
andrei.obuhovski писал(а):
ksetrin писал(а): Большинство так называемых "запросов" можно уместить в "магические методы". Сервисы просто для свалки запросов использовать - я бы не стал. Ибо лишняя прослойка должна быть всегда оправдана.
Сервисы - это прослойка логики, т.к. ее в контроллере не должно быть. Но и в сущностях ее не должно быть, т.к. логика может использовать несколько сущностей.
Аналог ModelForm и ModelSearch. Только ModelForm и ModelSearch конкретно для форм и поиска используются. Но логика разная бывает, поэтому ModelService.
ModelForm не совсем - все же это чистая модель (если в нее не пихать вспомогательных методов), а ModelSearch - в принципе да, смесь модели и сервиса.
Trampampam
Сообщения: 19
Зарегистрирован: 2015.12.07, 20:01

Re: Виджет, main.php или как не нужно делать?!

Сообщение Trampampam »

zelenin писал(а):пример:

Код: Выделить всё

public function actionCategory()
{
$dbContentFetcher = new DbContentFetcher;

$popular = $dbContentFetcher->getPopular(79, 5);
$news = $dbContentFetcher->getNews(79, 5);

return $this->render('category', ['popular' => $popular,'news'=>$news]);
}
это позволит сократить код в экшне (тонкий контроллер), вынести прямые запросы в БД в отдельный класс (S в слове SOLID), поднимет ваш опыт в глазах других (К в слове КРУТОЙ).

Статические и магические методы - зло, и их надо избегать.
Спасибо за пример. То, что доктор прописал.
Ответить