在laravel雄辩中获得枚举选项

时间:2014-11-18 10:03:59

标签: php laravel enums eloquent

在我的迁移文件中,我向表pages提供了一个enum字段,其中包含两个可能的值(如下所示)。我的问题是,如果可以用Laravels Eloquent 选择这些值吗?

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

我找到了几种解决方法,但必须有一些"雄辩的本地"处理这个问题的方法。我的预期输出将是这个(这将是完美的!):

array('draft','published')

提前谢谢!

4 个答案:

答案 0 :(得分:13)

不幸的是,Laravel没有为此提供解决方案。你必须自己做。我做了一些挖掘,发现了this answer

您可以使用该功能并将其转换为模型类中的方法......

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

你就像这样使用它

$options = Page::getPossibleStatuses();

如果您愿意,也可以使其更具普遍性和通用性。

首先,创建一个BaseModel。然后所有模型都应该从这个类扩展

class BaseModel extends Eloquent {}

之后,将此功能放在那里

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

你称之为

$options = Page::getPossibleEnumValues('status');

答案 1 :(得分:2)

对lukasgeiter的功能做了一点改进。他的答案中的foreach循环是解析字符串。您可以更新正则表达式来为您执行此操作。

/**
 * 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] : [];
}

答案 2 :(得分:1)

如果该列不存在,则抛出错误。所以我在代码中添加了一个小检查

DataPropertyName

答案 3 :(得分:0)

从L5.17开始,Eloquent不包含此功能,而是需要回退到本机QL。这是一个可以在一行中使用SQL的示例 - 返回一个像你问的数组。

本着一种班轮复杂性的精神;)

我把它扔在我的一个视图作曲家中 - 它从表中取出列,将其爆炸并组合数组中的值。

我使用foreach在我的视图中迭代它。

explode (
    "','",
    substr (
      DB::select("  SHOW COLUMNS 
                    FROM ".(new \Namespace\Model)->getTable()." 
                    LIKE 'colName'"
      )[0]->Type,
      6,
      -2
    )
);