Куда поместить/как обрабатывать перечисления в 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));
...
});
- Есть ли рекомендуемое место для их размещения?
- Могу ли я сделать их глобальными, чтобы я мог легко получить к ним доступ во всех своих представлениях?
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'));
Я не согласен с принятым здесь ответом. Я чувствую, что перечисления могут быть очень полезны для такого рода вещей. Я предпочитаю рассматривать перечисления как типы и реализовывать необходимые методы в базовом классе перечислений, чтобы предоставить вам необходимые функции, такие как получение словаря.
Мой простой пример ниже:
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 и перечисления для получения более подробной информации и более подробного примера.
Основываясь на ответе @Banfords, константы PHP7 теперь могут быть массивами:
class User extends Authenticatable
{
/**
* The possible genders a user can be.
*/
const GENDER = [
'Male',
'Female',
'Unspecified'
];
...
В дополнение к ответу @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
Я бы рекомендуется всегда устанавливать значения в целые числа и впоследствии сохранять их в БД в виде целых чисел.
Базовый класс перечисления имеет методы для получения всех ключей и значений в виде массивов. Пакет также имеет несколько других преимуществ, которые могут быть полезны в этом случае, таких как проверка - чтобы пользователь не мог добавить несуществующее значение в базу данных.
Также есть генератор, который довольно удобен.
Я надеюсь, что это кому-то пригодится.
Только что была аналогичная проблема, для меня Красноречивые средства доступа и мутаторы работали лучше всего. Для этого вопроса это будет выглядеть так:
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 - работа. Во-вторых, было бы разумно использовать переводы здесь вместо защищенной собственности.