Tak się prezentuje mój system uprawnień:
Ludzie składają zamówienia i biznes się kręci. W tabelce orders
jest bardzo ważne pole zip_code
, po który możemy rozpoznać na jakim obszarze odbyła się usługa. areas
to obszary, a area_codes
to tabela z kodami pocztowymi.
Powstało jednak wymaganie tego typu:
-
obszary mogą być dowolnie definiowane, tzn. może być Mokotów osobno i Ochota osobno (do każdego z nich jest przypisane wiele kodów pocztowych), ale Mokotów i Ochota razem mogą tworzyć nowy obszar pod tytułem Warszawa - Strefa 1. Stwierdziłem, że to świetny moment na użycie tworu zwanego nested set.
-
musi powstać możliwość nadawania użytkownikom uprawnień, które definiują zamówienia z której strefy użytkownik będzie widział na liście zamówień (np. użytkownik z uprawnieniem do Warszawa Strefa 1 widzi tylko te zamówienia, które polegają kodom pocztowym w obrębie Mokotowa i Ochoty - patrz tabelka niżej)
Problem pierwszy postanowiłem rozwiązań nested setem, dzięki czemu będzie można sobie dowolnie komponować te obszary.
Struktura tabeli prezentuje się teraz następująco:
Pierwszy punkt z głowy, teraz czas na drugi. Ponieważ jestem leniwy i chciałem wykorzystać swój system uprawnień stwierdziłem, że można proces tworzenia nowych zautomatyzować.
(Chciałem też załatwić wyciąganie tych zamówień jakimś sprytnym zapytaniem i uniknąć ifologi oraz dodawania warunków where osobno dla każdego uprawnienia.)
Podczas tworzenia nowego obszaru (co robi jakiś tam super koordynator) tworzy się automatycznie uprawnienie w tabelce permissions
pod tytułem strefa.warszawa.strefa.1
czy coś takiego. Jest ono wiązane z nową strefą (areas.permission_id
).
TL:DR
Chce wyciągnąć tylko takie zamówienia z tabeli orders
, gdzie zip_code
znajduje się w kodach pocztowych przypisanych do strefy, do której użytkownik ma uprawnienie.
Niestety mimo mojej usilnej walki z zapytaniem ni jak nie mogę sobie dać rady, żeby pobrać tylko te zamówienia, do których obszarów użytkownik ma uprawnienie. Można to zrobić na pałę po kolei wszystko wyciągając, ale mam wrażenie, że jest jakiś inne sposób tylko go nie widzę.
Jeżeli ktoś miał na tyle cierpliwości, żeby to przeczytać to super i mam nadzieję, że Ty drogi czytelniku coś zaproponujesz :) Chociaż znając życie metoda gumowej kaczuszki zadziała i zaraz wymyślę coś genialnego.
Używam mariadb w wersji, w której niestety nie ma jeszcze WITH
:(
@Edit
Dołączam strzępy SQL, może komuś coś pomogą:
-- pobieramy obszary, które są najwyżej w hierarchii
SELECT
a1.id,
a1.lft,
a1.rgt
FROM areas a1
WHERE a1.permission_id IN (6, 7); -- uprawnienie do warszawa strefa - 1 i strefa 2
-- załóżmy, że powyższe zapytanie zwraca Warszawa Strefa Pierwsza i Strefa Druga
-- więc musimy dociągnąć strefy podrzędne, oczywiście uprawnienia się
-- dziedziczą, jak ktoś ma uprawnienie do warszawa strefa pierwsza
-- to ma tez do wszystich "niżej", czyli po prost wyciągamy wszystkie dzieciaki
SELECT *
FROM orders
WHERE zip IN (
SELECT zip
FROM areas a
JOIN area_codes ac ON a.id = ac.area_id
WHERE
a.lft BETWEEN 2 AND 7 -- strefa 1
OR a.lft BETWEEN 8 AND 13 -- strefa 2
OR a.id IN (49, 50) -- id strefy 1 i strefy 2
)