FindOrFail

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Brainfuck
Сообщения: 313
Зарегистрирован: 2018.02.19, 14:20

Re: FindOrFail

Сообщение Brainfuck »

mkramer писал(а): 2018.06.01, 10:00
Brainfuck писал(а): 2018.06.01, 09:32 Как ты подмешаешь трейт в ActiveQuery?
Запилишь свой ActiveQuery для класса и к нему подмешаешь. Ну, правда, это я почти всегда перекрываю ActiveQuery, чтоб добавить функции для нужных мне выборок
Как? Модель не наследуется от ActiveQuery алло!!! Или что ты имеешь ввиду? Я не понимаю... Это к модели (AR) можно подмешать трейт с findOneOrFail, а чтобы изменить AQ надо переопределять AR - другого варианта нет.
Brainfuck
Сообщения: 313
Зарегистрирован: 2018.02.19, 14:20

Re: FindOrFail

Сообщение Brainfuck »

Кстати я вспомнил что еще надо переопределять помимо find - hasOne и hasMany. Связи тоже возвращают AQ и они причем не зависят от find! И я пока не придумал как их переопределить...
mkramer
Сообщения: 531
Зарегистрирован: 2014.12.14, 13:02

Re: FindOrFail

Сообщение mkramer »

Brainfuck писал(а): 2018.06.01, 10:29 Кстати я вспомнил что еще надо переопределять помимо find - hasOne и hasMany. Связи тоже возвращают AQ и они причем не зависят от find! И я пока не придумал как их переопределить...
Зависят. Всё на find() завязано
mkramer
Сообщения: 531
Зарегистрирован: 2014.12.14, 13:02

Re: FindOrFail

Сообщение mkramer »

Brainfuck писал(а): 2018.06.01, 10:21
Это к модели (AR) можно подмешать трейт с findOneOrFail, а чтобы изменить AQ надо переопределять AR - другого варианта нет.
Я о том, что если у меня модель Post, я в 90% случаев сделаю к ней PostQuery. Тем более с gii это одну галочку добавить. Да и без него строчек 7 дополнительных написать. А в него уже можно подмешать трейт
Brainfuck
Сообщения: 313
Зарегистрирован: 2018.02.19, 14:20

Re: FindOrFail

Сообщение Brainfuck »

mkramer писал(а): 2018.06.01, 13:18
Brainfuck писал(а): 2018.06.01, 10:29 Кстати я вспомнил что еще надо переопределять помимо find - hasOne и hasMany. Связи тоже возвращают AQ и они причем не зависят от find! И я пока не придумал как их переопределить...
Зависят. Всё на find() завязано
Зависеть то может и зависят, но IDE этого не знает и показывает ошибку при использовании моих методов из запроса полученного с помощью hasOne и hasMany.
chesar
Сообщения: 514
Зарегистрирован: 2013.04.10, 17:49

Re: FindOrFail

Сообщение chesar »

Brainfuck писал(а): 2018.06.01, 15:19 Зависеть то может и зависят, но IDE этого не знает и показывает ошибку при использовании моих методов из запроса полученного с помощью hasOne и hasMany.
Для этого нужно помочь IDE с PhpDoc или указать @return type для методов.

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


$config = [
    'container' => [
        'definitions' => [
            PostQuery::class => [
                ['class' => PostQuery::class],
                [Post::class],
            ],
            AuthorQuery::class => [
                ['class' => AuthorQuery::class],
                [Author::class],
            ],
        ],
    ],
    'components' => [
        //...
    ],
];

class PostQuery extends \yii\db\ActiveQuery
{
    public function published(): self
    {
        return $this->andWhere('[[status]]=:published', [':published' => Post::STATUS_PUBLISHED]);
    }

    // Можно вынести в трейт и цеплять к любым квери
    public function findOrFail($condition, $params = []): Post
    {
                               //или andWhere в зависимости от соглашения
        $model = $this->where($condition, $params)->one();
        if (!$model) {
            throw new NotFoundException();
        }
        return $model;
    }
}

class AuthorQuery extends \yii\db\ActiveQuery
{
    public function published(): self
    {
        ...
    }    
}

class Post extends \yii\db\ActiveRecord
{
    public static function find(): PostQuery
    {
        return new PostQuery(__CLASS__);
    }

    public function getAuthor(): AuthorQuery
    {
        return $this->hasOne(Author::class, ['id' => 'author_id']);
    }
}

class PostController extends \yii\web\Controller
{
    private $postRepository;

    public function __construct(string $id, $module, PostQuery $postRepository, array $config = [])
    {
        $this->postRepository = $postRepository;
        parent::__construct($id, $module, $config);
    }

    public function actionUpdate($id)
    {
        $post = $this->postRepository->findOrFail(['id' => $id]);
        if ($post->load($this->postParams) && $post->save()) {
            $post->getAuthor()->published()->one();
        }
        return $this->render('update', ['post' => $post]);
    }
}

Ответить