sql >> Database teknologi >  >> RDS >> Mysql

MySQL indlejrede ressourcer (pivottabeller) tilladelse til at se/opdatere/administrere

For at kontrollere, om en given model er relateret til en anden, hvilket er det, du vil have, hvis jeg forstår dig rigtigt, er alt, hvad du behøver, denne lille metode, hvor du får mest muligt ud af Eloquent :

(Implementer det i BaseModel , Entity eller et omfang, hvad end der passer dig)

// 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);

Magien sker her:

/**
 * 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, men hvad sker der?

isRelatedTo() fungerer sådan her:

  1. tjek om bestået $id er en model eller blot et id, og forbereder $related model og dens $id til brug ved tilbagekald. Hvis du ikke sender et objekt, skal Eloquent instansiere alle de relaterede modeller på $relations (relation1.relation2.relation3... ) kæde for at få den, vi er interesseret i - det er, hvad der sker i getNestedRelated() , ret ligetil.

  2. så skal vi gøre sådan noget:

    // 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. da vi ikke ved, hvor dybt relationen er indlejret, er vi nødt til at bruge gentagelse. Men vi sender en lukning til whereHas , så vi er nødt til at bruge et lille trick for at kalde sig selv inde i sin krop (faktisk kalder vi det ikke, men sender det snarere som $callback til whereHas metode, da sidstnævnte forventer en lukning som 2. param) - dette kan være nyttigt for dem, der ikke kender Anonyme rekursive PHP-funktioner :

    // save it to the variable and pass it by reference
    $callback = function () use (&$callback) {
      if (...) // call the $callback again
      else // finish;
    }
    
  4. vi går også videre til lukningen $relations (som et array nu) ved reference for at fjerne dets elementer, og når vi fik dem alle (det betyder, at vi indlejrede whereHas ), sætter vi endelig where klausul i stedet for en anden whereHas , for at søge efter vores $related model.

  5. lad os endelig returnere bool



  1. FEJL 1062 (23000):Dubleret indtastning '2147483647' for nøglen 'PRIMÆR'

  2. Søg efter alle forekomster af en streng i en mysql-database

  3. Lagring af hexadecimale værdier som binære i MySQL

  4. Stort databasestyringssystem:Design og arkitekt