Yii Active Record + isModified + dependencies clearing

В фреймворке Yii класс CActiveRecord позволяет получить доступ к данным реляционных баз данных в объектном стиле. Он реализует шаблон проектирования ORM — Object-relational mapping — объектно-реляционное проецирование. Классы, созданные на базе CActiveRecord, имеют реализации самых распространённых операций, которые нужны для работы с данными: создание, изменение, удаление отдельных записей, поиск записей по условиям. Каждый класс является проекцией одной таблицы. Также классы реализуют связи между строками нескольких таблиц.

Два существенных недостатка класса CActiveRecord — 1) нет возможности определить, изменился ли объект и отдельные его свойства, 2) очищать связи с объектами при изменении свойств, отвечающих за связи.

Класс ModActiveRecord решает эти две проблемы.

Код класса ModActiveRecord

Yii Active Record instance with is modified logic and dependencies clearing at gist.github.com

 

Пример кода с зависимостями и логикой «выполнить если изменилось» (if modified then sample)

Для примера требуется приложение на PHP на базе фреймворка Yii c настроенным подключением к базе данных. В базу данных нужно загрузить файл sample.sql

Очистка связей при изменении свойств в объекте Active Record (dependecies  clearing in ActiveRecord instance)

Код примера sample_01_clear_relations.php

При обращении к свойству $book->author, в память загружается экземпляр класса Author и связывается с $book

При изменении свойства $book->author_id связанный экземпляр класса Author удаляется из памяти.

При повторном обращении к свойству $book->author, в память загружается другой экземпляр класса Author.

Изменился ли объект Active Record (isModified active record instance) ?

Код примера sample_02_beforesave_ifmodified.php

Открывается экземпляр класса Book, изменяется свойство $book->author_id, затем объект сохраняется.

Перед сохранением вызывается метол Book::beforeSave() в котором проверяется, изменилось ли значение свойства $book->author_id. Выводятся старое и новое значение этого свойства.

Ссылки по теме:

Павел Волынцев

Уже более 15 лет занимаюсь разработкой веб-проектов. Fullstack Senior Developer. IT евангелист — доношу свет знаний об информационных технологиях. Профессиональные цели: Дать людям возможность дать людям больше.

Читайте также:

  • DrDeath72

    Могу ошибаться, но $relation->foreignKey может быть массивом

    • pavel_volyntsev

      Не проверял такой случай и в документации не могу найти.
      Вы не могли бы дать пример такой связи?

      • DrDeath72

        Дак в документации http://www.yiiframework.com/doc/guide/1.1/ru/database.arr и сам параметр описан как mixed

        • pavel_volyntsev

          Ок, я исправлю как могу. На случай сложных связей (использование атрибута в условиях соединения ON … GROUP … HAVING … ) придётся предусмотреть парсер условий 🙁 Или событие ModActiveRecortd::onModified()

  • pavel_volyntsev

    Решение ifModified then … (sample_02_beforesave_ifmodified.php) очень хорошо сочетается со сквозным кэшированием с использованием меток (Кэширование в Yii). Именно как сквозное кэширование активно используем — как только данные в базе изменились, синхронно обновляются данные в кэше.