web-dev-qa-db-ja.com

Laravelでenumをどこに/どのように処理するのですか?

Laravelには a <select> form helper これは、入力として辞書を受け取ります。私はこれらすべての価値を一元管理するのが好きです。たとえば、次のような列挙型があります。

$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. すべてのビューで簡単にアクセスできるように、それらをグローバルにできますか?
47
mpen

列挙型を処理するためのいくつかのオプションがあります。ただし、いくつかを見る前に、まずDB enum列タイプを使用することを強くお勧めしますnot

データベース列挙型には、いくつかの理由で問題があります。たとえば、この記事を読むことをお勧めします。

http://komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil/

それでは、他のいくつかのオプションを見てみましょう。

Laravel configを使用

Laravelを使用しているため、非常に簡単なオプションの1つは、構成ファイルにオプションの配列を貼り付けることです。

次のように新しいファイルconfig/enums.phpを作成するとします。

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

これで、Bladeテンプレートを含むコードのどこからでもconfig('enums.phone_types')にアクセスできます。

PHPパッケージを使用する

@Banfordの答えは、クラス定数を使用して基本的な列挙型の動作を行う方法を示しています。そのアプローチが好きなら、この概念に基づいて強く型付けされた列挙型を提供するこの記事とパッケージを見ることをお勧めします。

https://stitcher.io/blog/php-enums

https://github.com/spatie/enum

次のようなクラスを作成します。

/**
 * @method static self cell()
 * @method static self home()
 * @method static self work()
 */
class PhoneTypes extends Enum
{
}

これで、アプリでPhoneTypes::home()を呼び出すことができます。必要に応じて、そのパッケージのドキュメントを参照して、値のマップを作成する方法を確認してください。

DB関係の使用

データベースでオプションを管理したい場合本当に、別のphone_typesデータベーステーブルを作成し、customersとの関係を作成しますテーブル。これはstillenum列タイプを使用するよりもはるかに優れたオプションです。

54
jszobody

ここで受け入れられた答えに同意しません。列挙型は、この種のことに非常に役立つと思います。列挙型を型として扱い、必要なメソッドをEnum基本クラスに実装して、辞書の取得などの必要な機能を提供することを好みます。

以下の私の簡単な例:

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と列挙 を参照してください。

57
Banford

@Banfordsの答えに基づいて、PHP7定数は配列になりました:

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

...
11
Kirill Fuchs

@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

常に値を整数に設定し、その後でそれらをintとしてDBに保存することをお勧めします。

基本Enumクラスには、すべてのキーと値を配列として取得するためのメソッドがあります。このパッケージには、検証など、この場合に役立つ可能性のあるその他の利点もいくつかあります。これにより、ユーザーが存在しない値をDBに追加できなくなりました。

かなり便利なジェネレータもあります。

これが誰かに役立つことを願っています。

7
BenSampo

同様の問題がありました。私にとっては Eloquent Accessors and mutators が最適でした。この質問の場合、次のようになります。

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は仕事です。次に、保護されたプロパティの代わりにここで翻訳を使用するのが賢明です。

4
lchachurski

列挙型を使用しないでください。

公式のLaravel 5.1 ドキュメント 状態:

注:列挙列を使用したテーブルの列名の変更は現在サポートされていません。

データベーステーブルにenum列がある場合に発生します。 renameanother列を変更しようとしても、another columnをnullableに変更しようとしても、バグが表示されます。これはDoctrine\DBALの問題です。

不明なデータベースタイプの列挙が要求されました

laravel 5.8でも、問題は解決しません。

利用可能なオプションを追加するenum列宣言にある場合、同じ問題が発生することを追加する必要があります。

enumを注意して使用する必要があります。またはenumを使用しないでくださいという結論に至ります。

これがどれほど難しいかという例です利用可能なオプションを追加するenum列宣言に

あなたはこれを持っていると言います:

Schema::create('blogs', function (Blueprint $table) {
    $table->enum('type', [BlogType::KEY_PAYMENTS]);
    $table->index(['type', 'created_at']);
...

より多くのタイプを利用可能にする必要があります

public function up(): void
{
    Schema::table('blogs', function (Blueprint $table) {
        $table->dropIndex(['type', 'created_at']);
        $table->enum('type_tmp', [
            BlogType::KEY_PAYMENTS,
            BlogType::KEY_CATS,
            BlogType::KEY_DOGS,
        ])->after('type');
    });

    DB::statement('update `blogs` as te set te.`type_tmp` = te.`type` ');

    Schema::table('blogs', function (Blueprint $table) {
        $table->dropColumn('type');
    });

    Schema::table('blogs', function (Blueprint $table) {
        $table->enum('type', [
            BlogType::KEY_PAYMENTS,
            BlogType::KEY_CATS,
            BlogType::KEY_DOGS,
        ])->after('type_tmp');
    });

    DB::statement('update `blogs` as te set te.`type` = te.`type_tmp` ');

    Schema::table('blogs', function (Blueprint $table) {
        $table->dropColumn('type_tmp');
        $table->index(['type', 'created_at']);
    });
}
2