Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get enum options in laravels eloquent

Tags:

In my migration file, I gave my table pages a enum field with 2 possible values (as seen below). My question is, if it's possible to select these values with Laravels Eloquent?

$table->enum('status', array('draft','published'));

There are several Workarounds that I found, but there must be some "eloquent-native" way to handle this. My expected output would be this (that would be perfect!):

array('draft','published')

Thank you in advance!

like image 321
barfoos Avatar asked Nov 18 '14 10:11

barfoos


2 Answers

Unfortunately, Laravel does not offer a solution for this. You will have to do it by yourself. I did some digging and found this answer

You can use that function and turn it into a method in your model class...

class Page extends Eloquent {

    public static function getPossibleStatuses(){
        $type = DB::select(DB::raw('SHOW COLUMNS FROM pages WHERE Field = "type"'))[0]->Type;
        preg_match('/^enum\((.*)\)$/', $type, $matches);
        $values = array();
        foreach(explode(',', $matches[1]) as $value){
            $values[] = trim($value, "'");
        }
        return $values;
    }
}

And you use it like this

$options = Page::getPossibleStatuses();

If you want you can also make it a bit more universally accessible and generic.

First, create a BaseModel. All models should then extend from this class

class BaseModel extends Eloquent {}

After that, put this function in there

public static function getPossibleEnumValues($name){
    $instance = new static; // create an instance of the model to be able to get the table name
    $type = DB::select( DB::raw('SHOW COLUMNS FROM '.$instance->getTable().' WHERE Field = "'.$name.'"') )[0]->Type;
    preg_match('/^enum\((.*)\)$/', $type, $matches);
    $enum = array();
    foreach(explode(',', $matches[1]) as $value){
        $v = trim( $value, "'" );
        $enum[] = $v;
    }
    return $enum;
}

You call this one like that

$options = Page::getPossibleEnumValues('status');
like image 151
lukasgeiter Avatar answered Sep 27 '22 22:09

lukasgeiter


Made a small improvement to lukasgeiter's function. The foreach loop in his answer is parsing the string. You can update the regex to do that for you.

/**
 * Retrieves the acceptable enum fields for a column
 *
 * @param string $column Column name
 *
 * @return array
 */
public static function getPossibleEnumValues ($column) {
    // Create an instance of the model to be able to get the table name
    $instance = new static;

    // Pulls column string from DB
    $enumStr = DB::select(DB::raw('SHOW COLUMNS FROM '.$instance->getTable().' WHERE Field = "'.$column.'"'))[0]->Type;

    // Parse string
    preg_match_all("/'([^']+)'/", $enumStr, $matches);

    // Return matches
    return isset($matches[1]) ? $matches[1] : [];
}
like image 20
TheNatureBoy Avatar answered Sep 27 '22 21:09

TheNatureBoy