ActiveRecord - uniqcle/Yii2 GitHub Wiki
ActiveQuery object - Запрос к БД. Объект ActiveQuery собирает всю информацию, которую нужно выполнить.
# Создать объект запроса к БД. Вернет объект класса ActiveQuery
$query = Book::find();
# Каждый метод для модификации запроса изменяет внутреннее состояние query,
# поэтому query будет знать что ему делать
$query->where(['id' => 1]);
$query->orderBy('id');
$query->limit(2); //У объекта query вызываем метод limit
$books = $query->all();
На выходе получаем массив объектов класса books (атрибуты и методы), а в DAO массив.
return $this->render('index', compact('books') );
Примеры:
//В контроллере
public function actionActiverecord(){
$model = User::find()->all(); //Получаем все записи из таблицы User
$model = User::find()
->select('id')
->all(); //Выбрать только id
$model = User::find()
->select(['id', 'name', 'age']) //Выбрать id, name, age, где id = 1
->where(['id' => 1])
->orWhere(['age' => 30])
->all();
$model = User::find()
->select(['id', 'name', 'age'])
->where(['id' => 1, 'name' => 'Ivan'])
->all();
$books = Book::find()
//->where('id=1')
//->where(['id' => 2])
//->where(['like', 'title', 'книга']) //поиск по полю title
->where(['<', 'id', 7]) //записи, где id < 7
->orderBy(['id' => SORT_DESC ])
->limit(3)
//->count() //Подсчитывает кол-во записей
//->one() //Будет выбрана 1 запись
->all();
//$books = Book::findOne(['<', 'id', 7]);
//$books = Book::findAll(['id' => 2]);
$sql = "SELECT * FROM books WHERE title LIKE :search ";
$books = Book::findBySql( $sql, [':search' => '%книг%'] )->all();
return $this->render('index', compact('books'));
В frontend/controllers/shop/ProductController.php
namespace frontend\controllers\shop;
use yii\web\Controller;
use frontend\models\shop\Product;
class ProductController extends Controller
{
public function actionIndex(){
//Создать объект запроса к БД. Вернет объект класса ActiveQuery
$query = Product::find();
$brand = 1;
$query->where(['brand' => $brand]);
$query->limit(2); //У объекта query вызываем метод limit
$products = $query->all();
//или так. Используя шаблон проектирования "Текучий интерфейс"
//$products = Product::find()->where(['brand' => $brand])->limit(2)->all();
return $this->render('index', compact('products') );
}
}
В frontend/models/shop/Product.php
namespace frontend\models\shop;
use Yii;
use yii\db\ActiveRecord;
class Product extends ActiveRecord
{
//Изменяем БД на db2
public static function getDb(){
return Yii::$app->db2;
}
//Возвращает название таблицы с которой работаем
public static function tableName(){
return '{{products}}';
}
//Правила валидации
public function rules(){
return [
[['date_buy'], 'required']
];
}
//Метод для получения даты в модели
public function getDateBuy(){
//Если дата задана - вернем эту дату. Если нет - вернем строку Not Set
// Дату предварительно форматируем компонентом Yii::$app->formatter->asDatetime()
return ($this->date_buy) ? Yii::$app->formatter->asDatetime($this->date_buy, 'short') : 'Not Set' ;
}
//СВЯЗЬ ОДИН К ОДНОМУ
//Получаем объект связанные brands
public function getBrand(){
// hasOne() Получаем связь с брендами
// Параметры: название класса и колонки, кот. связаны, где
// id в таблице brands
// brand в таблице products
// Метод hasOne() вернет ActiveQuery, в кот. запрос уже готов.
// Останется только получить данные one()
return $this->hasOne(Brand::className(), ['id' => 'brand'])->one();
}
public function getBrandName(){
$brand = $this->getBrand() ;
if($brand){
return $brand->title;
}
return 'Not set';
}
//СВЯЗЬ МНОГОЕ КО МНОГИМ
/*
1. Создадим связь Products hasMany() ProductsOrders. СВЯЗЬ ОДИН КО МНОГИМ
2. Создадим ActiveRecord для Orders
3. Создадим связь Products hasMany() Orders ч/з промежуточную табл. ProductsOrders
*/
// Имея ID продукта мы можем найти заказы, связанные с этим продуктом через таблицу products_orders
//Получим связи products
public function getProductsToOrders(){
return $this->hasMany(ProductsOrders::className(), ['product_id' => 'id']);
}
public function getOrders(){
return $this->hasMany(Order::className(), ['id' => 'order_id'] )->via('productsToOrders')->all(); //без get с маленькой буквы
}
}
В frontend/models/shop/ProductsOrders.php
namespace frontend\models\shop;
use Yii;
/**
* This is the model class for table "products_orders".
*
* @property int $product_id
* @property int $order_id
* @property int $count
*/
class ProductsOrders extends \yii\db\ActiveRecord
{
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'products_orders';
}
/**
* @return \yii\db\Connection the database connection used by this AR class.
*/
public static function getDb()
{
return Yii::$app->get('db2');
}
}
В frontend/models/shop/Brand.php
namespace frontend\models\shop;
use Yii;
/**
* This is the model class for table "brands".
*
* @property int $id
* @property string $title
*/
class Brand extends \yii\db\ActiveRecord
{
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'brands';
}
/**
* @return \yii\db\Connection the database connection used by this AR class.
*/
public static function getDb()
{
return Yii::$app->get('db2');
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['title'], 'required'],
[['title'], 'string', 'max' => 45],
];
}
/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'title' => 'Title',
];
}
}
В frontend/views/shop/product/index.php
Продукты:
<?php foreach($products as $product): ?>
<h3>Продукт <?php echo $product->id; ?> </h3>
<p> <?=$product->price; ?></p>
<p> <?=$product->getDateBuy(); ?> </p>
<p><?php echo $product->getBrandName(); ?>
<h5>Кто заказал этот товар</h5>
<?php $orders = $product->getOrders(); ?>
<?php foreach($orders as $order): ?>
<p><?=$order->name.' '.$order->phone; ?></p>
<?php endforeach; ?>
</p>
<hr>
<?php endforeach; ?>
Контроллер frontend\controllers\BookshopController.php
namespace frontend\controllers;
use Yii;
use frontend\models\Book;
use frontend\models\Publishers;
class BookshopController extends \yii\web\Controller
{
public function actionIndex()
{
$model = new Book();
$model->title = 'Test book';
$model->publisher_id = 2;
$model->save();
return $this->render('index');
}
//Добавление книг в БД
public function actionCreate(){
$book = new Book();
$publishers = Publishers::getPublishers();
$formData = Yii::$app->request->post();
if($book->load( $formData ) && ( $book->save() ) ){
Yii::$app->session->setFlash('success', 'Данная книга добавлена в БД');
//Используется для обновления данных
//return $this->redirect(['bookshop/index']); //Редирект на др. страницу
return $this->refresh();
}
return $this->render('create', [
'book' => $book,
'publishers' => $publishers
]);
}
}
Модель frontend\models\Publishers.php
namespace frontend\models;
use Yii;
use yii\db\ActiveRecord;
use yii\base\Model;
use yii\helpers\ArrayHelper;
class Publishers extends ActiveRecord
{
public static function tableName(){
return '{{publishers}}';
}
//Через компонент db
public static function getPublishers(){
$sql = "SELECT * FROM publishers; ";
$result = Yii::$app->db->createCommand($sql)->queryAll();
return ArrayHelper::map( $result , 'id', 'name');
}
}
Модель frontend\models\Book.php
namespace frontend\models;
use yii\db\ActiveRecord;
class Book extends ActiveRecord
{
//Указываем классу Book с какой таблицей он должен работать
public static function tableName(){
return '{{books}}'; //Возвращает имя таблицы, с кот. будет работать данный класс
}
public function rules(){
return [
[['title'], 'required'],
[['publisher_id'], 'integer']
];
}
}
Вью frontend\views\bookshop\create.php
use yii\widgets\ActiveForm;
use yii\helpers\Html;
use yii\helpers\ArrayHelper;
?>
<h3>ADDING BOOK</h3>
<?php $form = ActiveForm::begin([
'options'=>[
'id' => 'testForm',
'class'=>'form-horizontal']
]);
?>
<?php echo $form->field($book, 'title'); ?>
<?php echo $form->field($book, 'publisher_id')->dropDownList($publishers); ?>
<?php echo Html::submitButton('Отправить', ['class' => 'btn btn-primary']); ?>
<?php ActiveForm::end(); ?>
Контроллер frontend\controllers\lib\AuthorController.php
namespace frontend\controllers\lib;
use Yii;
use frontend\models\lib\Author;
class AuthorController extends \yii\web\Controller
{
//ПРОСМОТР
public function actionIndex()
{
$authors = Author::find()->all();
return $this->render('index', [
'authors' => $authors
]);
}
//СОЗДАНИЕ НОВОГО АВТОРА
public function actionCreate()
{
$author = new Author();
$formData = Yii::$app->request->post();
if( $author->load($formData) && $author->save() ){
Yii::$app->session->setFlash('success', 'Новый автор добавлен');
return $this->refresh();
}
return $this->render('create', [
'author' => $author
]);
}
//РЕДАКТИРОВАНИЕ
public function actionUpdate($id)
{
$author = Author::findOne($id);
$formData = Yii::$app->request->post();
if( $author->load($formData) && $author->save() ){
Yii::$app->session->setFlash('success', 'Данные автора обновлены');
return $this->redirect(['lib/author/index']);
}
return $this->render('update', [
'author' => $author
]);
}
//УДАЛЕНИЕ
public function actionDelete($id)
{
$author = Author::findOne($id);
$author->delete();
Yii::$app->session->setFlash('danger', 'Данная запись удалена!');
return $this->redirect(['lib/author/index']);
}
}
Модель Author frontend\models\lib\Author.php
namespace frontend\models\lib;
use Yii;
/**
* This is the model class for table "authors".
*
* @property int $id
* @property string $name
*/
class Author extends \yii\db\ActiveRecord
{
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'authors';
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['name'], 'string', 'max' => 11],
[['last_name'], 'string', 'max' => 256]
];
}
/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Имя автора',
];
}
public function getFullAuthorsName(){
return $this->name.' '.$this->last_name;
}
}
Вью Index frontend\views\lib\author\index.php
/* @var $this yii\web\View */
/* var $authors frontend\models\lib\Author */
use yii\helpers\Url;
?>
<h1>Список авторов</h1>
<div class="container">
<div class="row">
<a href = "<?php echo Url::to(['lib/author/create']);?>" class = "btn btn-success"> Добавить нового автора </a>
</br>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name of Author</th>
<th scope="col">Update</th>
<th scope="col">Delete</th>
</tr>
</thead>
<tbody>
<?php foreach($authors as $author): ?>
<tr>
<th scope="row"><?=$author->id; ?></th>
<td><?=$author->getFullAuthorsName(); ?></td>
<td><a href = "<?php echo Url::to(['lib/author/update', 'id' => $author->id]); ?>" class = "btn btn-info btn-sm"> Update </a></td>
<td><a href = "<?php echo Url::to(['lib/author/delete', 'id' => $author->id]); ?>" class = "btn btn-danger btn-sm">Delete</a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
Вью Create frontend\models\lib\author\create.php
<?php
/* @var $this yii\web\View */
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\Url;
?>
<h1>Create New Author</h1>
<?php $form = ActiveForm::begin(); ?>
<?php echo $form->field($author, 'name'); ?>
<?php echo $form->field($author, 'last_name'); ?>
<?php echo Html::submitButton('Добавить', ['class' => 'btn btn-success']); ?>
<?php ActiveForm::end(); ?>
</br>
<a href = "<?php echo Url::to(['lib/author/index']); ?>">Назад</a>
Вью Update frontend\models\lib\author\update.php
/* @var $this yii\web\View */
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\Url;
?>
<h1>Update Author</h1>
<?php $form = ActiveForm::begin(); ?>
<?php echo $form->field($author, 'name'); ?>
<?php echo $form->field($author, 'last_name'); ?>
<?php echo Html::submitButton('Изменить', ['class' => 'btn btn-success']); ?>
<?php ActiveForm::end(); ?>
</br>
<a href = "<?php echo Url::to(['lib/author/index']); ?>">Назад</a>
Пример ActiveRecord
find
findOne
findAll
findBySql
select
where
andwhere
orwhere
orderBy
all
one
save
insert
delete
//В контроллере
public function actionActiverecord(){
$model = User::find()->all(); //Получаем все записи из таблицы User
$model = User::find()->select('id')->all(); //Выбрать только id
$model = User::find()->select(['id', 'name', 'age'])->all(); //Выбрать id, name, age
$model = User::find()->select(['id', 'name', 'age'])->where(['id' => 1])->all(); //Выбрать id, name, age, где id = 1
$model = User::find()->select(['id', 'name', 'age'])->where(['id' => 1])->orWhere(['age' => 30])->all();
$model = User::find()->select(['id', 'name', 'age'])->where(['id' => 1, 'name' => 'Ivan'])->all();
$model = User::find()->select(['id', 'name', 'age'])->where(['id' => 1])->andWhere(['name' => 'Ivan'])->all(); //или так
$model = User::find()->select(['id', 'name', 'age'])->orderBy(['id' => SORT_DESC])->all(); // ->one() если 1 запись нужно вывести
$model = User::findOne(1); //Если нужно быстро извлечь 1 запись c id = 1
$model = User::findBySql('SELECT * FROM `user`')->all();
//Вставка Save()
$user = new User;
$user->name = 'Andrey';
$user->email = 'email@email';
$user->age = '35';
if( $user->save() ){ //insert() добавляет новые значения, а save() может апдейтить данные
echo 'success';
}
//Удаление delete()
$user->User::findOne(10);
$user->delete();
$user->User::find()->where(['id' => 11])->one();
$user->delete();
return $this->render('activerecord', [
'model' => $model
]);
}
//Во View
foreach($model as $user):
$user->id;
$user->name;
$user->surname;
endforeach;