2014-04-30 14 views
12

Po utworzeniu klasy modelu, która rozszerza klasę Eloquent Model Laravel, czy istnieje sposób na określenie, czy właściwość/atrybut mapuje do tabeli, a zatem czy można ją zapisać w tabeli?Laravel Wymowne atrybuty modelu

Na przykład mam tabelę announcements z kolumnami id, text i "created_by".

Skąd mam wiedzieć, czy created_by jest atrybutem i czy zostanie zapisany, jeśli zostanie ustawiony?

$announcement = new Announcement(); 

isset($announcement->created_by) zrozumiałe zwraca false jeśli nie jawnie ustawić jeszcze wartość. Próbowałem różnych funkcji odziedziczonych po klasie Eloquent, ale jak dotąd żaden z nich nie zadziałał. Szukam czegoś takiego:

$announcement->doesThisMapToMyTable('created_by'), która zwraca wartość true, niezależnie od tego, czy została ustawiona $announcement->created_by.

+1

Mattcore, należy rozważyć ustawienie @Leith [prosta odpowiedź] (http://stackoverflow.com/a/40057527/3810453) jako zaakceptowane. Jest prosty i krótki i zrobi to, o co prosiłeś, dzięki – Zanshin13

Odpowiedz

5

Dla laravel 5.4:

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

    if($hasCreatedAt == true) { 
     ... 
    } 
+0

Tak, tak ładnie i prosto. Każdy, kto korzysta z Laravel 5.4, powinien przyjąć tę odpowiedź. –

19

Jeśli model jest wypełniony danymi można:

$announcement = Announcement::find(1); 

$attributes = $announcement->getAttributes(); 

isset($attributes['created_by']); 

przypadku pustych modeli (nowe modele), niestety będzie musiał dostać kolumny za pomocą małego siekać. Dodaj tę metodę do BaseModel:

<?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; 
    } 

} 

Rozszerz swój model z niego:

class Announcement extends BaseModel { 

} 

Wtedy będziesz w stanie:

$columns = $announcement->getAllColumnsNames(); 

isset($columns['created_by']); 
+0

Dzięki, ale zarówno $ ogłoszenie-> atrybuty, jak i $ announcement-> getAttributes() zwrócą NULL. – mattcrowe

+0

Tak, w pustych modelach nie masz do nich dostępu, dlatego właśnie dodałem metodę, której używam w moich aplikacjach. –

+0

Użycie isset() dało mi problemy na moim Ubuntu Server 12.04 LTS z PHP 5.5. – sidneydobber

-1

Kiedyś !empty($announcement->created_by) i to dzieło idealne dla my

4

Zamiast pisać własne odnośniki do elementów wewnętrznych bazy danych, można po prostu użyć t on Schema facade zajrzeć do kolumny:

use Illuminate\Support\Facades\Schema; 

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

laravel 5,4

użyłem Leiths odpowiedź stworzyć ogólną metodę pomocniczą, która automatycznie mapuje JS-obiekt do laravel model (i zasadniczo ignoruje te właściwości, które nie są częścią modelu, dzięki czemu unika się komunikatów o błędach QueryBuilder dla niezdefiniowanych kolumn). Dodatkowo zawiera prostą createOrEdit, podejścia (choć nie ma -validation "ID nie istnieje?"):

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; 
 
    }

Powiązane problemy