Supposons que j'ai la requête suivante,
{ "id": 3, "slug": "omnis-et-harum-atque", "name": "Omnis et harum atque", "page_content": { "id": 3, "subject_type": "App\\Listing", "subject_id": 3, "html_title": "Omnis et harum atque", "meta_title": "Omnis et harum atque", ... and a load more stuff I don't want, "created_at": "2019-05-23 09:16:37", "updated_at": "2019-05-23 09:16:37" } }
$ results
inclura les colonnes de sélection spécifiées (ce qui est tout ce dont j'ai besoin), mais aussi, toutes les données pour page_contents
,
$results = Listing::select('listings.id', 'listings.slug', 'page_contents.html_title AS name') ->join('page_contents', function ($join) { $join->on('page_contents.subject_id', '=', 'listings.id') ->where('page_contents.subject_type', '=', 'App\Listing'); }) ->get();
Comment supprimer page_content
des données renvoyées. Les données sont renvoyées pour une API et les informations de page_data
sont donc bien au-dessus.
Laravel 5.8
Cheers
p >
3 Réponses :
Une astuce simple ferait l'affaire: À l'intérieur de votre liste de modèles: utilisez l'attribut $ hidden = ['pageContent ou quel que soit le nom de votre relation à la table']; Lors de la sérialisation, cette relation sera masquée par défaut, vous devrez la rendre visible quand vous le souhaitez.
Pas tout à fait ce dont j'avais besoin mais m'a mis sur la bonne voie. C'est un cas unique où je veux que les données supplémentaires soient exclues, donc les exclure par défaut n'a pas de sens. J'ai trouvé la méthode pour l'exclure des éléments de la collection - makeHidden ()
. À votre santé.
ouais, ça pourrait aussi faire l'affaire. C'est similaire à makeVisible. Dans les deux cas, cela fonctionnera.
Essayez de sélectionner après avoir rejoint et utilisez peut-être une simple déclaration de jointure?:
$results = Listing::join('page_contents','page_contents.subject_id', '=', 'listings.id') ->where('page_contents.subject_type', '=', 'App\Listing') ->select('listings.id', 'listings.slug', 'page_contents.html_title AS name') ->get();
PS. Je ne sais pas comment votre requête renvoie même le résultat sans aucun appel get () ou first () ou peut-être que vous n'avez pas fourni la requête complète.
J'espère que cela aide em>
Je ne peux pas utiliser une jointure smiple car il s'agit d'une relation polymorphe et l'ajout de la sélection après la jointure ne fait aucune différence. De plus, j'avais laissé de côté -> get ()
, car je supprimais des morceaux de code qui n'étaient pas pertinents et qui m'avaient emporté - maintenant mis à jour. À votre santé
Je vais mettre cette réponse ici car c'est ainsi que j'ai résolu le problème, j'ai l'impression qu'il y a un meilleur moyen de se cacher quelque part. La solution semble reposer sur le fait que la jointure est une relation définie sur le modèle. Ce serait bien de pouvoir exclure les données au niveau de la requête.
Pour exclure des données des éléments d'une collection, makeHidden ()
peut être utilisé.
$results->getCollection()->makeHidden('pageContent');
Si vous utilisez -> paginate ($ size)
au lieu de -> get ()
,
$results = Listing::select('listings.id', 'listings.slug', 'page_contents.html_title AS name') ->join('page_contents', function ($join) { $join->on('page_contents.subject_id', '=', 'listings.id') ->where('page_contents.subject_type', '=', 'App\Listing'); }) ->get(); $results->makeHidden('pageContent');
Vous devriez voir quel sql est généré en ajoutant
}) -> toSql ();
puisdd ($ results);
.