Laravel использовать поле сводки для фильтрации полиморфизма c отношение многие ко многим - PullRequest
0 голосов
/ 03 апреля 2020

Я прикрепляю пользовательские права доступа к нескольким различным моделям, используя полиморф c отношение «многие ко многим» - сводная таблица называется permissables:

Permissables
- id
- user_id
- permissable_type
- permissable_id
- role
- created_at
- updated_at

Это работает хорошо - я может вернуть список разрешенных пользователей для моей модели Project, используя:

public function users()
{
    return $this->morphToMany(User::class, 'permissable')->withPivot('role')->withTimestamps();
}

Если я хочу отфильтровать это только для владельцев - ie, где поле сводки role равно owner - Я могу сделать следующее в Tinker:

Project::first()->users->where('pivot.role', '=', 'owner')

Но если я попробую это в моей модели:

public function owners()
{
    return $this->users()->where('pivot.role', '=', 'owner');
}

, когда я вызываю Project->owners в Tinker, я получаю ошибку:

>>> Project::first()->owners
[!] Aliasing 'Project' to 'App\Project' for this Tinker session.
Illuminate/Database/QueryException with message 'SQLSTATE[HY000]: General error: 1 no such column: pivot.role (SQL: select "users".*, "permissables"."permissable_id" as "pivot_permissable_id", "permissables"."user_id" as "pivot_user_id", "permissables"."permissable_type" as "pivot_permissable_type", "permissables"."role" as "pivot_role", "permissables"."created_at" as "pivot_created_at", "permissables"."updated_at" as "pivot_updated_at" from "users" inner join "permissables" on "users"."id" = "permissables"."user_id" where "permissables"."permissable_id" = 1 and "permissables"."permissable_type" = App/Project and "pivot"."role" = owner)'

1 Ответ

0 голосов
/ 03 апреля 2020

По первому вопросу:

return $this->users->where('pivot.role', '=', 'owner');

Эта строка работает, потому что $this->users возвращает коллекцию пользователей со сводным значением (имя ключа pivot). И вы используете where-метод для фильтрации пользователей collection .

Для второго вопроса:

$this->users() измените код laravel к сырому sql как:

select users.*, permissables.permissable_id as pivot_permissable_id, permissables.user_id as pivot_user_id, permissables.permissable_type as pivot_permissable_type, permissables.role as pivot_role, permissables.created_at as pivot_created_at, permissables.updated_at as pivot_updated_at
from users 
inner join permissables on users.id = permissables.user_id 
where permissables.permissable_id = 1 and permissables.permissable_type = "App/Project"

Итак Промежуточная таблица имя permissables, а не pivot. Mysql не может найти столбец промежуточного объекта при применении where('pivot.role', 'owner') к users().

Laravel предоставляет метод wherePivot, который добавит имя промежуточной таблицы для вас.

public function owners()
{
    return $this->users()->wherePivot('role', 'owner'); // change to where pemissables.role = 'owner'
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...