Куда поместить/как обрабатывать перечисления в Laravel?


У Laravel есть помощник по форме <select>, который принимает в качестве входных данных словарь. Мне нравится держать ценности для всего этого в центре внимания. Например, у меня может быть перечисление, которое выглядит следующим образом:

$phoneTypes = [
    'CELL' => "Cellular",
    'HOME' => "Home",
    'WORK' => "Work",
];

Который я хочу использовать как в своем представлении/шаблоне, так и в базе данных:

Schema::create('customers', function (Blueprint $table) {
    $table->increments('id');
    $table->enum('pri_phone_type',array_keys($phoneTypes));
    ...
});
  1. Есть ли рекомендуемое место для их размещения?
  2. Могу ли я сделать их глобальными, чтобы я мог легко получить к ним доступ во всех своих представлениях?
Author: mpen, 2014-09-07

5 answers

Лично я бы вообще избегал типа столбца БД enum. Типы столбцов базы данных enum могут быть проблематичными, смотрите здесь одну статью на эту тему.

Обработка перечислений в БД с помощью отношений

Если вы действительно хотите управлять своим списком в базе данных, я бы создал отдельную таблицу базы данных phone_types и установил связь с вашей таблицей customers.

Обработка перечислений в вашем коде с помощью конфигурации Laravel

Также довольно легко управлять перечислениями в коде и полностью избегайте базы данных.

Поскольку вы используете Laravel, я думаю, что настройка конфигурационного файла была бы приемлемым вариантом.

Допустим, вы создаете новый файл config/enums.php со следующим:

return [
    'phone_types' => [
        'CELL' => "Cellular",
        'HOME' => "Home",
        'WORK' => "Work",
    ]
];

Теперь вы можете довольно легко передать это помощнику по форме:

Form::select('phone', Config::get('enums.phone_types'));
 42
Author: jszobody, 2018-09-04 19:00:46

Я не согласен с принятым здесь ответом. Я чувствую, что перечисления могут быть очень полезны для такого рода вещей. Я предпочитаю рассматривать перечисления как типы и реализовывать необходимые методы в базовом классе перечислений, чтобы предоставить вам необходимые функции, такие как получение словаря.

Мой простой пример ниже:

abstract class PhoneType extends Enum {
    const Cell = "Cellular";
    const Home = "Home";
    const Work = "Work";
}

abstract class Enum {
    static function getKeys(){
        $class = new ReflectionClass(get_called_class());
        return array_keys($class->getConstants());
    }
}

Пример использования:

PhoneType::getKeys();

Смотрите PHP и перечисления для получения более подробной информации и более подробного примера.

 45
Author: Banford, 2017-05-23 12:10:38

Основываясь на ответе @Banfords, константы PHP7 теперь могут быть массивами:

class User extends Authenticatable
{
    /**
     * The possible genders a user can be.
     */
    const GENDER = [
        'Male',
        'Female',
        'Unspecified'
    ];

...
 8
Author: Kirill Fuchs, 2017-05-08 10:34:39

В дополнение к ответу @Banford:

Недавно я собрал пакет, который делает работу с перечислениями в Laravel намного приятнее. Это комбинация различных реализаций, которые я нашел, исследуя, как сделать то же самое (следовательно, почему я здесь).

Https://github.com/BenSampo/laravel-enum

В этом случае вы могли бы сделать что-то вроде следующего:

final class PhoneTypes extends Enum
{
    const Cellular = 0;
    const Work = 1;
    const Home = 2;
}

Затем к значениям можно получить доступ с помощью:

PhoneTypes::Work // 1

Я бы рекомендуется всегда устанавливать значения в целые числа и впоследствии сохранять их в БД в виде целых чисел.

Базовый класс перечисления имеет методы для получения всех ключей и значений в виде массивов. Пакет также имеет несколько других преимуществ, которые могут быть полезны в этом случае, таких как проверка - чтобы пользователь не мог добавить несуществующее значение в базу данных.

Также есть генератор, который довольно удобен.

Я надеюсь, что это кому-то пригодится.

 4
Author: BenSampo, 2017-09-11 18:45:54

Только что была аналогичная проблема, для меня Красноречивые средства доступа и мутаторы работали лучше всего. Для этого вопроса это будет выглядеть так:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Customer extends Model
{
    /**
    * @var array
    */
    protected $phoneTypes = [
        'Cellular',
        'Home',
        'Work'
    ];

   /**
    * @param int $value
    * @return string|null
    */
    public function getPhoneTypeAttribute($value)
    {
        return Arr::get($this->phoneTypes, $value);
    }
}

Пожалуйста, обратите внимание, что в базе данных вы должны сохранять числовые значения, где 0 - ячейка, 1 - дом, а 2 - работа. Во-вторых, было бы разумно использовать переводы здесь вместо защищенной собственности.

 3
Author: lchachurski, 2017-06-24 11:01:04