Страница 1 из 1
Alias полей в ActiveRecord
Добавлено: 2020.01.15, 14:24
tlcl444w1plvc6c
Имеется таблица в базе данных в которой много полей и красивые названия.
Хотелось бы создавать ActiveRecord модели в каждой из которых задавать какие поля из таблицы использовать для неё и возможность задать алиансы этим полям.
Пример:
Имеется таблица myTable с полями: id, test1, test2, test3, test4, bla1, bla2, bla3, bla4
Код: Выделить всё
class My extends ActiveRecord {
public function tableName() {
return 'mytable';
}
public function useFields() {
return ['id', 'test1', 'test2', 'test3', 'test4'];
}
public function fieldsAliase() {
return ['test1' => 'name', 'test2' => 'title', 'test3' => 'order', 'test4' => 'counter'];
}
}
$obj = new My();
$obj->name = 'String'; // запишет String в поле test1
$obj->save();
$query = My::find()->one();
echo $query->name; // вернёт значение из поля test1
echo $query->bla1; // ошибка, такого поля нет так как оно не задано в useFields.
Как реализовать?
Re: Alias полей в ActiveRecord
Добавлено: 2020.01.17, 08:00
maleks
tlcl444w1plvc6c писал(а): ↑2020.01.15, 14:24
Имеется таблица в базе данных в которой много полей и красивые названия.
может
не красивые названия?
Re: Alias полей в ActiveRecord
Добавлено: 2020.01.17, 12:57
yiiliveext
Примерно так
Код: Выделить всё
class My extends ActiveRecord {
public function tableName() {
return 'mytable';
}
public function useFields() {
return ['id', 'test1', 'test2', 'test3', 'test4'];
}
public function fieldsAliase() {
return [ 'name' => 'test1', 'title' => 'test2', 'order' => 'test3', 'counter' => 'test4'];
}
public function __get($name)
{
$aliases = $this->fieldsAliase();
$fields = $ths->useFields();
if (is_array($fields) && in_array($name, $filelds)) {
if (is_array($aliases) && array_key_exists($name, $aliases)) {
return parent::__get($aliases[$name]);
}
return parent::__get($name);
} elseif (array_key_exists($name, $this->_related)) {
return parent::__get($name);
}
$value = parent::__get($name);
if ($value instanceof ActiveRecordInterface || is_array($value) || is_null($value)) {
return $value;
}
throw new InvalidArgumentException(get_class($this) . ' has no attribute named "' . $name . '".');
}
public function __set($name, $value)
{
$aliases = $this->fieldsAliase();
$fields = $ths->useFields();
if (is_array($fields) && in_array($name, $filelds)) {
if (is_array($aliases) && array_key_exists($name, $aliases)) {
parent::__set($aliases[$name], $value);
return;
} else {
parent::__set($name, $value);
return;
}
} elseif (array_key_exists($name, $this->_related)) {
parent::__set($name, $value);
return;
}
$value = parent::__get($name);
if ($value instanceof ActiveRecordInterface || is_array($value)) {
parent::__set($name, $value);
return;
}
throw new InvalidArgumentException(get_class($this) . ' has no attribute named "' . $name . '".');
}
}
Но тут есть рад нюансов, будет недоступна магия обычных сеттеров и геттеров, будут некоторые нюансы со связями (все можно устранить, но решение этой задачи за рамками поста).
Если убрать ограничение на использование определенных полей, то этих недостатков не будет.
Код: Выделить всё
class My extends ActiveRecord {
public function tableName() {
return 'mytable';
}
public function fieldsAliase() {
return [ 'name' => 'test1', 'title' => 'test2', 'order' => 'test3', 'counter' => 'test4'];
}
public function __get($name)
{
$aliases = $this->fieldsAliase();
if (is_array($aliases) && array_key_exists($name, $aliases)) {
return parent::__get($aliases[$name]);
}
return parent::__get($name);
}
public function __set($name, $value)
{
$aliases = $this->fieldsAliase();
if (is_array($aliases) && array_key_exists($name, $aliases)) {
parent::__set($aliases[$name], $value);
} else {
parent::__set($name, $value);
}
}
}
Re: Alias полей в ActiveRecord
Добавлено: 2020.01.17, 12:58
Шлфк
Если из таблицы будет только чтение, то можно сделать view `v_myTable`и переориентировать model на него. А во view уже сделать названия "красивыми"
Код: Выделить всё
Select test1 as [name] test2 as [title] ... From myTable
В таком случае в model добавляется функция
public static function tableName()
{
return 'v_myTable';
}
Если предполагается чтение/запись то такой вариант не пройдет (или пройдет, если сервер позволяет делать обновляемые view, то, на сколько я знаю, это редкость)
Re: Alias полей в ActiveRecord
Добавлено: 2020.01.17, 19:47
tlcl444w1plvc6c
Большое спасибо за помощь!