ActiveRecord - uniqcle/Yii2 GitHub Wiki

Getting Data

ActiveQuery object - Запрос к БД. Объект ActiveQuery собирает всю информацию, которую нужно выполнить.

# Создать объект запроса к БД. Вернет объект класса ActiveQuery
$query = Book::find(); 

1) Методы модификации запроса

# Каждый метод для модификации запроса изменяет внутреннее состояние query, 
# поэтому query будет знать что ему делать
$query->where(['id' => 1]);
$query->orderBy('id');         
$query->limit(2);              //У объекта query вызываем метод limit

2) Методы получения данных

$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'));

Example Getting Data

В 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; ?>

Inserting Data

Контроллер 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(); ?>

Updating & Deleting Data

Контроллер 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>

Example

Пример 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; 
⚠️ **GitHub.com Fallback** ⚠️