Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
CDbCriteria и array. В таком случае логично переписать сеттер который приводил бы тип к нужному. Но абсолютно везде — имхо, это лишний код и тупо усложняет.setAttributes, который в свою очередь смотрит на валидаторы, и при сохранении проверяет валидность. Другие присвоения (например, присвоение критерии EMongoDocumentDataProvider) реализованный внутри соответствующего расширения и нам не надо заботиться об этом. Присвоения свойств экшена — это уже чисто на нашей совести. Но Yii нам помогает: если мы присвоим несуществующую вьюху или скоуп — он нам однозначно даст нам об этом знать.class X extends CComponent
{
public function setField($value)
{
// ...
}
public function getField($name)
{
// ...
}
}
$x = new X();
$x->field = 'test';
echo $x->field;
public function setUser(User $user) {
...
}Если предметная область правильно спроектирована, у нас всегда будет простой способ получить связанные данные. И это абсолютно решает проблему с тем, что контроллер нам не передал список заказов.
foreach($client->orders as $order)$client->orders. Например, если он реализован с помощью релейшена AR — выборка будет единоразовой. В трейте для релейшенов yiimongodbsuite, который я написал, данные так же кешируется. foreach(Client::model->findAll() as $client) {
$order = $client->order;
...
}
SELECT * FROM order WHERE id IN (<список айдишников полученных ранее>)$user->posts
userWithPosts.php:<?php
$this->renderPartial('user', ['user' => $user]);//Эта вьюха понятия не имеет про посты пользователя
$this->renderPartial('posts', ['posts' => $posts]);//А эта - не знает ничего, кроме постов. И скорее всего предпочитает CDataProvider
На самом деле, выборки и фильтрации делают тоже модели.
Против SQL в контроллере любой немедленно возмутится, однако, когда тот же SQL в том же контроллере написан неявно — все почему-то довольны.
Car с свойством color, есть метод контроллера show($id) и list($color_filter = null). Когда в первом мы дергаем что-то вроде $car = Car::findByPK($id) — это к бизнес-логике не относится, простая инициализация, чистая логика хранения, так? Почему же когда во втором дергаем что-то типа $cars = Car::findByColor($color), то это становится бизнес-логикой — ведь та же инициализация? public function actions()
{
return [
'view1' => [
'class' => ARViewAction::class,
'modelClass' => User::class,
'criteria' => [
'with' => [
'orders' => [
'condition' => 'sum < 1000'
]
]
]
]
];
}
public function actions()
{
return [
// Если вьюха подразумевает что ей передают dataProvader'ы
// в AR метода getRelationCriteria(relationName, additionalCriteria) нет, но его можно самому дописать
'view2' => [
'class' => ARViewAction::class,
'modelClass' => User::class,
'dataProviders' => function(User $user){
return [
'ordersDataProvider' => [
'modelClass' => Order::class,
'criteria' => $user->getRelationCriteria('orders', 'sum < 1000')
]
];
}
],
];
}
Но все же во вьюхах его непосредственное присутствие создает путаницу. Я много раз видел (да чего греха таить, и сам так делал), как логику представления выносили в контроллер (какие-то специальные методы для форматирования или что-то подобное) лишь по тому-что контроллер присутствовал во всех его вьюхах.
Еще вопрос как быть с логикой вывода во вьюхах? К примеру если есть посты — вывести, если нет — сказать что постов нет
<?php /** @var Post[] $posts */ ?>
<?php $posts = $user->getPosts() ?>
<?php if (count($posts) > 0): ?>
<ul>
<?php /** @var Post $post */
<?php foreach($posts as $post): ?>
<li>
<h1><?php echo $post->getTitle() ?></h1>
<?php echo $post->getContent() ?>
</li>
<?php endforeach ?>
</ul>
<?php else: ?>
<?= _('no posts') ?>
<?php endif ?>
Правильное использование Yii