web-dev-qa-db-fra.com

Comment interroger raw via Eloquent?

J'essaie de faire une requête dans mon application Laravel et je veux utiliser une structure normale pour ma requête. Cette classe utilise soit Eloquent, donc je dois trouver quelque chose pour faire une requête totalement brute.

Peut-être quelque chose comme Model::query($query);. Seulement ça ne marche pas.

20
Chilion

utilisez DB::statement('your raw query here'). J'espère que cela t'aides.

14
Ray

Vous pouvez essayer ceci:

// query can't be select * from table where
Model::select(DB::raw('query'))->get();

Un exemple:

Model::select(DB::raw('query'))
     ->whereNull('deleted_at')
     ->orderBy('id')
     ->get();

En outre, vous pouvez utiliser quelque chose comme ceci (en utilisant le générateur de requêtes):

$users = DB::table('users')
                 ->select(DB::raw('count(*) as user_count, status'))
                 ->where('status', '<>', 1)
                 ->groupBy('status')
                 ->get();

En outre, vous pouvez essayer quelque chose comme ceci (en utilisant le générateur de requêtes):

$users = DB::select('select * from users where id = ?', array(1));
$users = DB::select( DB::raw("select * from users where username = :username"), array('username' => Input::get("username")));

Plus d’informations sur Raw-Expressions sur Site Web de Laravel .

42
The Alpha

Je ne pense pas que vous puissiez le faire par défaut. J'ai étendu Eloquent et ajouté la méthode suivante.

/**
 * Creates models from the raw results (it does not check the fillable attributes and so on)
 * @param array $rawResult
 * @return Collection
 */
public static function modelsFromRawResults($rawResult = [])
{
    $objects = [];

    foreach($rawResult as $result)
    {
        $object = new static();

        $object->setRawAttributes((array)$result, true);

        $objects[] = $object;
    }

    return new Collection($objects);
}

Vous pouvez ensuite faire quelque chose comme ceci:

class User extends Elegant { // Elegant is my extension of Eloquent

     public static function getWithSuperFancyQuery()
     {
         $result = DB::raw('super fancy query here, make sure you have the correct columns');
         return static::modelsFromRawResults($result);
     }
 }
6
Matthijn

Vous pouvez utiliser la fonction hydrate() pour convertir votre tableau en modèles Eloquent, que Laravel lui-même en interne utilise pour convertir les résultats de la requête en modèles. Pour autant que je sache, ce n'est pas mentionné dans la documentation.

Le code ci-dessous est équivalent à $userModels = User::where('id', '>', $userId)->get();:

$userData = DB::select('SELECT * FROM users WHERE id > ?', [$userId]);
$userModels = User::hydrate($userData);

La fonction hydrate() est définie dans \Illuminate\Database\Eloquent\Builder comme suit:

/**
 * Create a collection of models from plain arrays.
 *
 * @param  array  $items
 * @return \Illuminate\Database\Eloquent\Collection
 */
public function hydrate(array $items) {}
3
Orkhan Alikhanov

Ancienne question, déjà répondu, je sais.

Cependant, personne ne semble mentionner la classe Expression.

Certes, cela ne réglera peut-être pas votre problème car votre question laisse entrevoir où la condition Raw doit être incluse dans le code SQL (est-ce dans l’instruction SELECT ou l’instruction WHERE?). Cependant, cette information pourrait vous être utile malgré tout.

Incluez la classe suivante dans votre fichier modèle:

use Illuminate\Database\Query\Expression;

Puis, dans la classe Model, définissez une nouvelle variable

protected $select_cols = [
    'id', 'name', 'foo', 'bar',
    Expression ('(select count(1) from sub_table where sub_table.x = top_table.x) as my_raw_col'), 'blah'
]

Et ajouter une portée:

public function scopeMyFind ($builder, $id) {
    return parent::find ($id, $this->select_cols);
}

Ensuite, depuis votre contrôleur ou votre fichier logique, vous appelez simplement:

$rec = MyModel::myFind(1);
dd ($rec->id, $rec->blah, $rec->my_raw_col);

Jours heureux.

(Fonctionne dans le framework Laravel 5.5)

3
cartbeforehorse

Vous pouvez raccourcir le traitement de vos résultats en écrivant

$objects = new Collection(array_map(function($entry) {
    return (new static())->setRawAttributes((array) $entry, true);
}, $result));
0
Mathias Lieber