This was bugging me so I created a trait that will add this function to any model:
For example if you have a simple model:
// Example mode
class SaleOrder extends Model
{
// Add the trait
use HasSchemaAccessors;
// All fields are assignable except the id
protected $guarded = ['id'];
}
Then you add this class to your project. Make sure the folder matches its namespace:
namespace App\Models\Eloquent\Traits;
use Illuminate\Support\Facades\Schema;
trait HasSchemaAccessors {
public static $schemaInstance;
public static $schemaColumnNames;
public static $schemaTableName;
/**
* @return Illuminate\Database\Eloquent\Model
* Returns singleton of model
*/
protected static function schemaInstance() {
if(empty(static::$schemaInstance)) {
static::$schemaInstance = new static;
}
return static::$schemaInstance;
}
/**
* @return string
* Returns the table name for a given model
*/
public static function getSchemaTableName() {
if(empty(static::$schemaTableName)) {
static::$schemaTableName = static::schemaInstance()->getTable();
}
return static::$schemaTableName;
}
/**
* @return array
* Fetches column names from the database schema
*/
public static function getSchemaColumnNames() {
if(empty(static::$schemaColumnNames)) {
static::$schemaColumnNames = Schema::getColumnListing(static::getSchemaTableName());
}
return static::$schemaColumnNames;
}
/**
* @param $name
* @return bool
*/
public static function schemaHasColumn($name) {
return in_array( $name, static::getSchemaColumnNames() );
}
}
Now let's say you are in a Controller and you want to know if a column exists in the sale order table all you need to do is this:
/**
* index
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request) {
...
$columns = [Array of column names]
...
foreach ($columns as $column) {
if(SaleOrder::schemaHasColumn($column)) {
dump( "Sale Order table DOES have the column '$column'" );
}
}
}
Every time you call
Illuminate\Support\Facades\Schema::getColumnListing
Or when you call
Illuminate\Support\Facades\Schema::hasColumnName($tableName, $columnName)
Laravel just passes it on to Doctrine DBAL Schema object which then queries your database. This is the safest way to get column names, as even if the table is empty it will still return valid results. However if you do it from within a looping structure, you might accidentally create many, many requests to your database.
So.... I had to get this info from within a looping structure which is why I made this code.
I hope someone sees it and feels it is helpful.