Поиск аксессора загруженного отношения из таблиц данных
У меня есть следующие модели:
<?php
class User extends Model {
public function department() {
return $this->hasOne(Department::class);
}
}
class Department extends Model {
protected $appends = ["email"];
public function getEmailAttribute() {
return "$this->name@$this->domain";
}
public function user() {
return $this->belongsTo(User::class);
}
}
Я собираю список пользователей, включая их отделы, и показываю это (используя пакет Laravel DataTables) в виде данных с разбивкой на страницы на сервере / сортировкой / поиском:
<?php
class UserController extends Controller {
public function dt() {
$users = User::with("department")
->where("location_id", session("current_location"));
return DataTables::of($users)->make();
}
}
В настройке datatables один из моих столбцов определяется следующим образом:
{data: "department.email"}
Это отображает email
свойство accessor без проблем. Проблема возникает, когда я пытаюсь выполнить поиск или сортировку по этому столбцу:
Предупреждение DataTables: идентификатор таблицы =DataTables_Table_0 - Сообщение об исключении:
SQLSTATE [42S22]: Столбец не найден: 1054 Неизвестный столбец "partments.email"в" предложении where "
Очевидно, datatables не знает, что это средство доступа, и пытается включить его в запрос - с предсказуемыми результатами.
Единственный обходной путь, на который я мог найти ссылку, - это использование filterColumn
метод, который позволяет определить пользовательский WHERE
предложение для конкретного столбца. Но, насколько я могу судить, а) требует, чтобы вы определяли столбец вручную с помощью построителя запросов, и б) работает только с моделью напрямую, а не с одним из ее отношений.
Есть ли способ, которым я могу искать и сортировать это свойство аксессора так же, как я могу с "реальными" свойствами отношения?
2 ответа
Итак, вот как я решил это. Это не идеальное решение, но в основном я воссоздал аксессор в SQL, вручную построил запрос, а затем использовал Datatables'filterColumn
функциональность.
<?php
class UserController extends Controller {
public function dt() {
$concat = "CONCAT(departments.name, '@', departments.domain)";
$users = User::select(["users.*", DB::raw("$concat AS dept_email")])
->leftJoin("departments", "users.department_id", "=", "departments.id")
->whereNull("departments.deleted_at")
->where("location_id", session("current_location"))
->with("departments");
return DataTables::of($users)
->filterColumn(
"dept_email",
function($q, $k) use ($concat) {
return $q->whereRaw("$concat LIKE ?", ["%$k%"]);
}
)
->make();
}
}
Затем я просто включил сгенерированный столбец в определение своей таблицы, и поиск работал должным образом.
Вы можете попробовать установить: https://github.com/babenkoivan/scout-elasticsearch-driver
Этот пакет предлагает возможность определения пользовательских правил для SQL-запросов.
Увидеть:
Попробуйте добавить аксессуар к модели.
class Department extends Model {
protected $appends = ['email'];
// the rest of your code
}
Примечание: атрибуты в appends
массив также будет уважать visible
а также hidden
Настройки настроены на модель.
Источник: Добавление значений в JSON