web-dev-qa-db-fra.com

Laravel Eloquent: Comment obtenir uniquement certaines colonnes des tables jointes

J'ai 2 tables jointes dans Eloquent, à savoir des thèmes et des utilisateurs.

modèle de thème:

public function user() {
  return $this->belongs_to('User');
}

modèle d'utilisateur:

public function themes() {
  return $this->has_many('Theme');
}

Mon appel api éloquent se présente comme suit:

return Response::eloquent(Theme::with('user')->get());

Ce qui renvoie toutes les colonnes du thème (c'est bien) et toutes les colonnes de l'utilisateur (pas bien). Je n'ai besoin que de la colonne 'nom d'utilisateur' du modèle utilisateur, comment puis-je limiter la requête à cela?

93
ralu

Modifiez votre modèle pour spécifier les colonnes que vous souhaitez sélectionner:

public function user() {
  return $this->belongs_to('User')->select(array('id', 'username'));
}

Et n'oubliez pas d'inclure la colonne sur laquelle vous vous inscrivez.

100
user2317976

Pour Laravel> = 5.2

Utilisez la méthode -> pluck ()

$roles = DB::table('roles')->pluck('title');

Si vous souhaitez récupérer un tableau contenant les valeurs d'une seule colonne, vous pouvez utiliser la méthode pluck


Pour Laravel <= 5.1

Utilisez la méthode -> lists ()

$roles = DB::table('roles')->lists('title');

Cette méthode renverra un tableau de titres de rôle. Vous pouvez également spécifier une colonne de clé personnalisée pour le tableau renvoyé:

37
Javi Stolz

Vous pouvez fournir un tableau de champs dans le paramètre get comme suit:

return Response::eloquent(Theme::with('user')->get(array('user.username'));

UPDATE (for Laravel 5.2) À partir de la docs , vous pouvez procéder comme suit:

$response = DB::table('themes')
    ->select('themes.*', 'users.username')
    ->join('users', 'users.id', '=', 'themes.user_id')
    ->get();
28
Melvin

Je sais, vous demandez Eloquent mais vous pouvez le faire avec Fluent Query Builder

$data = DB::table('themes')
    ->join('users', 'users.id', '=', 'themes.user_id')
    ->get(array('themes.*', 'users.username'));
21
aykut

Voici comment je le fais

$posts = Post::with(['category' => function($query){
        $query->select('id', 'name');
      }])->get();

La première réponse de user2317976 n'a pas fonctionné pour moi, j'utilise laravel 5.1

15
Sajjad Ashraf

Une autre option consiste à utiliser la propriété $hidden du modèle pour masquer les colonnes que vous ne souhaitez pas afficher. Vous pouvez définir cette propriété à la volée ou définir les valeurs par défaut de votre modèle.

public static $hidden = array('password');

Maintenant, le mot de passe des utilisateurs sera masqué lorsque vous retournerez la réponse JSON.

Vous pouvez également le définir à la volée de la même manière.

User::$hidden = array('password');
11
Jason Lewis

Utiliser avec la pagination

$data = DB::table('themes')
->join('users', 'users.id', '=', 'themes.user_id')
->select('themes.*', 'users.username')
->paginate(6);
9
Nufayl

user2317976 a introduit un excellent moyen statique de sélectionner les colonnes de tables associées.

Voici une astuce dynamique que j'ai trouvée pour que vous puissiez obtenir tout ce que vous voulez en utilisant le modèle:

return Response::eloquent(Theme::with(array('user' => function ($q) {
    $q->addSelect(array('id','username'))
}))->get();

Je viens de trouver que cette astuce marche aussi bien avec load (). C'est très pratique.

$queriedTheme->load(array('user'=>function($q){$q->addSelect(..)});

Assurez-vous également d'inclure la clé de la table cible, sinon elle ne pourra pas la trouver.

6
KinoP

Par ici:

Post::with(array('user'=>function($query){
    $query->select('id','username');
}))->get();
6
Specs

Je sais que cette question est ancienne, mais si vous créez une API, comme le fait l'auteur de la question, utilisez des transformateurs de sortie pour effectuer de telles tâches.

Transofrmer est une couche entre le résultat de votre requête de base de données et un contrôleur. Il permet de contrôler et de modifier facilement ce qui va être envoyé à un utilisateur ou à un consommateur d'API.

Je recommande Fractal comme base solide de votre couche de transformation de sortie. Vous pouvez lire la documentation ici .

5
Armen Markossyan

Sur Laravel 5.5, la manière la plus propre de procéder est la suivante:

Theme::with('user:userid,name,address')->get()

Vous ajoutez deux points et les champs que vous souhaitez sélectionner séparés par une virgule et sans espace entre eux.

4
JoeGalind

Dans Laravel 4, vous pouvez empêcher le renvoi de certains champs en ajoutant les éléments suivants dans votre modèle.

protected $hidden = array('password','secret_field');

http://laravel.com/docs/eloquent#converting-to-arrays-or-json

4
John Veldboom

en utilisant Model:

Model::where('column','value')->get(['column1','column2','column3',...]);

tilisation du générateur de requêtes:

DB::table('table_name')->where('column','value')->get(['column1','column2','column3',...]);
2
srmilon

Si j'ai bien compris, ce qui est renvoyé est correct sauf que vous ne voulez voir qu'une seule colonne. Si c'est le cas, ceci devrait être beaucoup plus simple:

return Response::eloquent(Theme::with('user')->get(['username']));
0
Kornel