web-dev-qa-db-fra.com

Laravel Eloquent Model Attributes

Après avoir instancié une classe de modèle qui étend la classe de modèle Eloquent de Laravel, existe-t-il un moyen de déterminer si la propriété/l'attribut est mappé sur la table et peut donc être enregistré dans la table?

Par exemple, j'ai une table announcements avec les colonnes id, text et "created_by".

Comment savoir que created_by est un attribut et sera sauvegardé s'il est défini?

$announcement = new Announcement();

isset($announcement->created_by) renvoie naturellement false si je n'ai pas encore explicitement défini la valeur. J'ai essayé diverses fonctions héritées de la classe de modèles Eloquent, mais aucune n'a fonctionné jusqu'à présent. Je cherche quelque chose comme:

$announcement->doesThisMapToMyTable('created_by') qui renvoie true, que $announcement->created_by ait été défini ou non.

14
mattcrowe

Pour Laravel 5.4:

$hasCreatedAt = \Schema::hasColumn(app(Model::class)->getTable(), 'created_at');

    if($hasCreatedAt == true) {
       ...
    }
6
mindsupport

Si votre modèle est rempli de données, vous pouvez:

$announcement = Announcement::find(1);

$attributes = $announcement->getAttributes();

isset($attributes['created_by']);

Pour les modèles vides (nouveaux modèles), vous devrez malheureusement obtenir les colonnes avec un petit hack. Ajoutez cette méthode à votre modèle de base:

<?php

class BaseModel extends Eloquent {

    public function getAllColumnsNames()
    {
        switch (DB::connection()->getConfig('driver')) {
            case 'pgsql':
                $query = "SELECT column_name FROM information_schema.columns WHERE table_name = '".$this->getTable()."'";
                $column_name = 'column_name';
                $reverse = true;
                break;

            case 'mysql':
                $query = 'SHOW COLUMNS FROM '.$this->getTable();
                $column_name = 'Field';
                $reverse = false;
                break;

            case 'sqlsrv':
                $parts = explode('.', $this->getTable());
                $num = (count($parts) - 1);
                $table = $parts[$num];
                $query = "SELECT column_name FROM ".DB::connection()->getConfig('database').".INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'".$table."'";
                $column_name = 'column_name';
                $reverse = false;
                break;

            default: 
                $error = 'Database driver not supported: '.DB::connection()->getConfig('driver');
                throw new Exception($error);
                break;
        }

        $columns = array();

        foreach(DB::select($query) as $column)
        {
            $columns[$column->$column_name] = $column->$column_name; // setting the column name as key too
        }

        if($reverse)
        {
            $columns = array_reverse($columns);
        }

        return $columns;
    }

}

Étendez votre modèle à partir de celui-ci:

class Announcement extends BaseModel {

}

Ensuite, vous pourrez:

$columns = $announcement->getAllColumnsNames();

isset($columns['created_by']);
23

Plutôt que d'écrire votre propre recherche dans les éléments internes de la base de données, vous pouvez simplement utiliser la façade Schema pour rechercher les colonnes:

use Illuminate\Support\Facades\Schema;

$announcement = new Announcement();
$column_names = Schema::getColumnListing($announcement->getTable());
if (isset($column_names['created_by'])) {
  // whatever you need
}
7
Leith

Laravel 5.4

J'ai utilisé Leiths answer pour créer une méthode d'assistance générique, qui mappe automatiquement l'objet JS au modèle de Laravel (et ignore essentiellement les propriétés qui ne font pas partie du modèle, évitant ainsi les messages d'erreur QueryBuilder pour les colonnes non définies). Contient en outre une méthode simple createOrEdit (même si elle n'a pas la valeur "l'ID existe-t-il?"):

    public function store(Request $request) {
        if($request->input("club")) {
            $club = \App\Club::find($request->input("club")["id"]);
        } else {
            $club = new \App\Club;
        }
        $club = self::mapModel($request->input("club"), $club);
        $club->save();
    }
    
    public function mapModel($input,$model) {
        $columns = Schema::getColumnListing($model->getTable());
        foreach ($columns as $i => $key) {
            if($input[$key]) {
                $model->{$key} = $input[$key];
            }
        }
        return $model;
    }

0
Janne

!empty($announcement->created_by) et j’ai travaillé très bien pour mon

0
morawcik