Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Eloquent Model Attributes

Tags:

After instantiating a model class that extends Laravel's Eloquent Model class, is there a way to determine if the property/attribute maps to the table, and therefore can be saved to the table?

For example, I have a table announcements with columns id, text and "created_by".

How can I know created_by is an attribute and will be saved if set?

$announcement = new Announcement(); 

isset($announcement->created_by) understandably returns false if I haven't explicitly set the value yet. I have tried various functions inherited from the Eloquent model class, but so far none have worked. I'm looking for something like:

$announcement->doesThisMapToMyTable('created_by') that returns true whether or not $announcement->created_by has been set.

like image 288
mattcrowe Avatar asked Apr 30 '14 19:04

mattcrowe


2 Answers

If your model is filled with data, you can:

$announcement = Announcement::find(1);  $attributes = $announcement->getAttributes();  isset($attributes['created_by']); 

For empty models (new Models), unfortunately you will have to get the columns using a small hack. Add this method to your 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;     }  } 

Extend your model from it:

class Announcement extends BaseModel {  } 

Then you will be able to:

$columns = $announcement->getAllColumnsNames();  isset($columns['created_by']); 
like image 198
Antonio Carlos Ribeiro Avatar answered Oct 14 '22 05:10

Antonio Carlos Ribeiro


Rather than writing your own lookup into the database internals, you can just use the Schema facade to look up the columns:

use Illuminate\Support\Facades\Schema;  $announcement = new Announcement(); $column_names = Schema::getColumnListing($announcement->getTable()); if (in_array('created_by', $column_names)) {   // whatever you need } 

Alternatively, as early as Laravel 4 there's the hasColumn() check:

use Illuminate\Support\Facades\Schema;  $announcement = new Announcement(); if (Schema::hasColumn($announcement->getTable(), 'created_by')) {   // whatever you need } 
like image 24
Leith Avatar answered Oct 14 '22 03:10

Leith