Jump to content

Active Records

Что такое активная запись?

Invision Community широко реализует паттерн Active Record, где каждый активный объект записи представляет собой строку в вашей базе данных, и объект предоставляет методы для взаимодействия с этой строкой (включая добавление новых строк). Далее по тексту будем называть активная запись. Например, поскольку модель \IPS\Member возвращает активную запись, мы можем получать и взаимодействовать с строкой пользователем в базе данных следующим образом:

$member = \IPS\Member::load(1);
$member->name = "Валера";
$member->save();

Основной класс активной записи в Invision Community - \IPS\Patterns\ActiveRecord. Большинство классов моделей, с которыми вы будете работать (включая \IPS\Node\Model, \IPS\Content\Item, \IPS\Content\Comment и \IPS\Content\Review), паттерн активной записи, что означает, что все они предлагают совместимый интерфейс для работы с вашими данными.

Важно, чтобы вы использовали методы, предоставленные активной записью, а не напрямую обращались к базе данных, так как при добавлении дополнительных функций к вашему элементу контента, методы будут выполнять более сложные задачи. 

Настройка классов ActiveRecord

При написании класса, который расширяет \IPS\Patterns\ActiveRecord в цепочке наследования (даже если вы не расширяете непосредственно его), вам нужно указать некоторые свойства, которые позволяют классу находить записи в базе данных. Вот они:

public static $databaseTable = 'string';

Обязательное. Задает таблицу базы данных, к которой относится данный ActiveRecord.

public static $databasePrefix = 'string';

Необязательное. Указывает префикс поля, используемый этой таблицей. Например, если ваша таблица имеет поля item_id, item_name, item_description и так далее, то свойство $databasePrefix может быть установлено как item_. Это позволяет автоматически сопоставлять свойства со столбцами базы данных.

public static $databaseColumnId = 'string';

Необязательное (по умолчанию: 'id'). Задает поле первичного ключа этой таблицы базы данных.

Загрузка записей

static \IPS\Patterns\ActiveRecord load( int $id [, string $idField=NULL [, mixed $extraWhereClause=NULL ]] )

Пример:

$row = \IPS\YourClass::load(1);

Этот метод извлекает строку с идентификатором 1 из базы данных и возвращает её как экземпляр активной записи вашего класса.

  • $id (Integer; обязательный) - Идентификатор первичного ключа для загрузки.
  • $idField (строка; необязательный) - столбец базы данных, относящийся к параметру $id (NULL будет использовать static::$databaseColumnId).
  • $extraWhereClause (Mixed; optional) - Дополнительный оператор where (смотрите \IPS\Db::build).

Выбрасывается исключение InvalidArgumentException, если $idField не существует в таблице, или исключение OutOfRangeException, если запись с данным идентификатором не найдена. 

Примечание. Этот метод не проверяет права пользователя на загружаемый элемент. При написании класса, который расширяет одну из моделей контента (\IPS\Node\Model, \IPS\Content\Item, \IPS\Content\Comment или \IPS\Content\Review, к примеру), вы должны вместо этого использовать loadAndCheckPerms, когда загружаете данные для фронтэнда. Этот метод с такой же конструкцией, что и методы load выше, но loadAndCheckPerms выбросит исключение OutOfRangeException, если у пользователя нет разрешения на просмотр записи.

static \IPS\Patterns\ActiveRecord constructFromData( array $data [, boolean $updateMultitonStoreIfExists=TRUE] )

Пример

$row = \IPS\YourClass::constructFromData( \IPS\Db::i()->select(...)->first() );

Если вы извлекли строку базы данных ручным запросом (например, чтобы получить самую последнюю запись), и вам нужно создать объект ActiveRecord из данных, этот метод позволит вам сделать это без необходимости вызова load (что вызовет другой запрос к базе данных).

  • $data (Массив; обязательный) - Строка базы данных, вернувшаяся от \IPS\Db как массив.
  • $updateMultitonStoreIfExists (Boolean; необязательный) - Если true, обновит текущий кэшированный объект, если он существует для данного ID.

Обновление данных в ActiveRecord

Вы можете получить или установить данные для записи просто установив свойства объекта, которые сопоставляются с именами столбцов базы данных. Если вы настроили свойство $databasePrefix в вашем классе, тогда вы не должны включать префикс при ссылке на свойства.

Пример (если в нашей таблице базы данных содержатся столбцы с названием title и description):

$item = \IPS\YourClass::load( 1 );
$item->title = "Заголовок моей статьи";
echo $item->description;

Обратите внимание, что для фактического обновления базы данных метод save следует вызывать после внесения всех изменений (см. ниже).

Если вашему классу необходимо выполнить обработку свойств перед их получением или установкой, вы можете определить геттеры или сеттеры для каждого свойства, добавив метод с именем get_<значение> или set_<значение>. В рамках этих методов вы можете получить доступ к необработанным значениям, используя массив $this->_data.

Пример, переводящий свойство title в верхний регистр:

// YourClass.php
public function set_title( $title )
{
	$this->_data['title'] = strtoupper( $title );
}

// OtherClass.php
$item = \IPS\YourClass::load( 1 );
$item->title = 'my title';
echo $item->title;

//--> 'MY TITLE'

Сохранение и удаление записей

void save()

Пример:

$item = \IPS\YourClass::load( 1 );
$item->title = 'New Title';
$item->save();

После изменения данных в ActiveRecord для обновления базы данных необходимо вызвать save.

void delete()

Пример:

$item = \IPS\YourClass::load( 1 );
$item->delete();

Удаляет строку из базы данных.

Клонирование записей

Вы можете просто клонировать записи с помощью выражения clone. \IPS\Patterns\ActiveRecord гарантирует, что первичные ключи настраиваются по мере необходимости. Обратите внимание, что вам все равно нужно вызвать save после клонирования, чтобы создать запись в базе данных.

$item = \IPS\YourClass::load( 1 );
$copy = clone $item;
$copy->save();
echo $copy->id;

//--> 2

Использование побитовых флагов

Класс ActiveRecord реализует поразрядную функцию, позволяющую хранить несколько логических значений в одном поле, без необходимости добавлять в вашу модель новые поля (и, следовательно, столбцы базы данных). Под капотом побитовое поле хранится как целое (integer). Вы определяете свои побитовые флаги как ключи с числовым значением; это числовое значение удваивается для каждого добавляемого вами нового значения (так порядок будет таким 1, 2, 4, 8, 16, 32 и т. д.).

public static $bitOptions = array(
    'model_bitoptions'	=> array(
        'model_bitoptions'	=> array(
            'property_1'		=> 1,			// Некоторые опции для этой модели
            'property_2'		=> 2,			// Другая опция для этой модели
            'property_3'		=> 4			// Третья опция для модели
        )
    )
);

В этом примере таблица базы данных нашей модели будет иметь столбец с именем model_bitoptions - и мы используем это имя в массиве $bitOptions для его идентификации. Мы сохраняем три варианта, но вы можете определить больше, следуя шаблону удвоения значения каждый раз. Хорошая практика прокомментировать каждый вариант, объясним, что делает каждый параметр.

Ваша модель ActiveRecord автоматически предоставит объект \IPS\Patterns\Bitwise для этого столбца, который реализует \ArrayAccess, позволяя вам получать и устанавливать значения, поскольку это был массив:

/* Получение значения */
if ( $object->model_bitoptions[‘property_1’] ) {
	// ...
}

/* Установка значения - помните, что это может быть только TRUE или FALSE! */
$object->model_bitoptions[‘property_2’] = FALSE;
$object->save();

/* Получение строк базы данных */
$rowsWithPropery1AsTrue = \IPS\Db::i()->select( ‘*’, ‘table’, \IPS \Db::i()->bitwiseWhere( \IPS\YourClass::$bitOptions['model_bitoptions'], 'property_1' ));

 




Messenger

    ×
    ×
    • Create New...

    Important Information

    By using our site you agree to our Privacy Policy