У меня есть некоторые модели, которые используют геопространственные поля, такие как POINT
, MULTIPOLYGON
или MULTIPOLYGON
. Я хотел бы сказать моей модели, чтобы обработать эти атрибуты особым образом, чтобы получить желаемые атрибуты модели.
Пример. Каждый регулярный метод Model::find()
или другой метод Eloquent должен применять некоторый пользовательский код перед сохранением или после извлечения значения базы данных.
$area->surface
– поле POLYGON
в MySQL, но в моем классе модели я хотел бы обрабатывать $area->surfare
как массив точек.
В SELECT
я хотел бы: 1) получить значение с использованием необработанного выражения, чтобы получить текстовое представление значения, и 2) пройти через собственный код PHP, чтобы преобразовать строку WKT в массив.
В INSERT/UPDATE
я хотел бы взять значение атрибута (массив) и 1) преобразовать его в строку WKT, после чего 2) он записывается в базу данных с использованием оператора базы данных DB, который сохраняет значение.
Я хотел бы установить это на основе поля, а не как специальные функции get / set для каждого поля, а не в контроллерах, потому что у меня много геосетиальных полей.
Есть ли способ добиться этого в Ларавеле?
(Более абстрактная версия того же вопроса, как я могу создать код, который манипулирует значениями атрибутов для фактических SQL-запросов, а не просто некоторые манипуляции с использованием значений с помощью мутаторов и аксессуаров)
ОБНОВЛЕНИЕ: Глядя глубже в Laravel Doc и API, я обнаружил, что, возможно, метод Eloquent::newQuery()
– это то, что мне нужно манипулировать? Будет ли это использоваться для любого запроса независимо от того, будут ли SELECT
, INSERT
или UPDATE
?
Теперь мы решили эту проблему для всех моделей, расширив нашу базовую модель со следующими функционалами:
Вот выдержка из базовой модели, которую мы теперь используем:
/** * The attributes that hold geometrical data. * * @var array */ protected $geometry = array(); /** * Select geometrical attributes as text from database. * * @var bool */ protected $geometryAsText = false; /** * Get a new query builder for the model's table. * Manipulate in case we need to convert geometrical fields to text. * * @param bool $excludeDeleted * @return \Illuminate\Database\Eloquent\Builder */ public function newQuery($excludeDeleted = true) { if (!empty($this->geometry) && $this->geometryAsText === true) { $raw = ''; foreach ($this->geometry as $column) { $raw .= 'AsText(`' . $this->table . '`.`' . $column . '`) as `' . $column . '`, '; } $raw = substr($raw, 0, -2); return parent::newQuery($excludeDeleted)->addSelect('*', DB::raw($raw)); } return parent::newQuery($excludeDeleted); }
Если мутаторы и аксессуар не соответствуют вашим потребностям, вы можете управлять этими атрибутами с помощью событий модели .
Затем вы можете выполнять код при запуске некоторых из событий Eloquent: создание, создание, обновление, обновление, сохранение, сохранение, удаление, удаление, восстановление, восстановление.
Я думаю, что нет ничего плохого в использовании аксессуаров / мутаторов.
вы можете сослаться на мой ответ здесь, как я это сделал для аксессуар.
если вам нужен код для мутатора, (setter,), я могу добавить его здесь.