Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Zagnieżdżone zasoby MySQL (tabele przestawne) uprawnienia do przeglądania/aktualizowania/zarządzania

Aby sprawdzić, czy dany model jest powiązany z innym modelem, czego chcesz, jeśli dobrze się zorientuję, potrzebujesz tylko tej malutkiej metody, która w pełni wykorzystuje Eloquent :

(Zaimplementuj go w BaseModel , Entity lub zakres, cokolwiek Ci odpowiada)

// usage
$task->isRelatedTo('transactions.users', $id);
// or
$template->isRelatedTo('tasks.transactions.users', Auth::user());

// or any kind of relation:
// imagine this: User m-m Transaction 1-m Item m-1 Group
$group->isRelatedTo('items.transaction.users', $id);

Tutaj dzieje się magia:

/**
 * Check if it is related to any given model through dot nested relations
 * 
 * @param  string  $relations
 * @param  int|\Illuminate\Database\Eloquent\Model  $id
 * @return boolean
 */
public function isRelatedTo($relations, $id)
{
    $relations = explode('.', $relations);

    if ($id instanceof Model)
    {
        $related = $id;
        $id = $related->getKey();
    }
    else
    {
        $related = $this->getNestedRelated($relations);
    }

    // recursive closure
    $callback = function ($q) use (&$callback, &$relations, $related, $id) 
    {
        if (count($relations))
        {
            $q->whereHas(array_shift($relations), $callback);
        }
        else
        {
            $q->where($related->getQualifiedKeyName(), $id);
        }
    };

    return (bool) $this->whereHas(array_shift($relations), $callback)->find($this->getKey());
}

protected function getNestedRelated(array $relations)
{
    $models = [];

    foreach ($relations as $key => $relation)
    {
        $parent = ($key) ? $models[$key-1] : $this;
        $models[] = $parent->{$relation}()->getRelated();
    }

    return end($models);
}

Hej, ale co się tam dzieje?

isRelatedTo() działa tak:

  1. sprawdź, czy przeszedł $id jest modelem lub tylko identyfikatorem i przygotowuje $related model i jego $id do wykorzystania w wywołaniu zwrotnym. Jeśli nie przekażesz obiektu, Eloquent musi utworzyć instancję wszystkich powiązanych modeli na $relations (relation1.relation2.relation3... ) łańcuch, aby uzyskać ten, który nas interesuje - tak się dzieje w getNestedRelated() , całkiem proste.

  2. wtedy musimy zrobić coś takiego:

    // assuming relations 'relation1.relation2.relation3'
    $this->whereHas('relation1', function ($q) use ($id) {
       $q->whereHas('relation2', function ($q) use ($id) {
          $q->whereHas('relation3', function ($q) use ($id) {
             $q->where('id', $id);
          });
       });
    })->find($this->getKey()); 
    // returns new instance of current model or null, thus cast to (bool)
    
  3. ponieważ nie wiemy, jak głęboko zagnieżdżona jest relacja, musimy użyć cykliczności. Jednak przekazujemy zamknięcie do whereHas , więc musimy użyć małej sztuczki, aby wywołać siebie w swoim ciele (w rzeczywistości nie wywołujemy tego, ale raczej przekazujemy go jako $callback do whereHas metoda, ponieważ ta ostatnia oczekuje zamknięcia jako drugiego parametru) — może to być przydatne dla osób nieznanych Anonimowe rekurencyjne funkcje PHP :

    // save it to the variable and pass it by reference
    $callback = function () use (&$callback) {
      if (...) // call the $callback again
      else // finish;
    }
    
  4. przechodzimy również do zamknięcia $relations (teraz jako tablica) przez odwołanie w celu cofnięcia przesunięcia jej elementów i kiedy otrzymaliśmy je wszystkie (co oznacza zagnieżdżenie whereHas ), w końcu umieściliśmy where klauzula zamiast innego whereHas , aby wyszukać nasze $related model.

  5. na koniec zwróćmy bool



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Utwórz kolumnę sumy skumulowanej w MySQL

  2. Jak przekonwertować dane Blob w MYSQL na Android ImageView

  3. Zapytanie o wybór między serwerami MySQL

  4. MySQL myśli, że podzapytanie jest pochodną, ​​gdy tak nie jest!

  5. MySQL:Ustaw zmienną użytkownika z wyniku zapytania