migracje laravel programu budującego schematy unikatowe w dwóch kolumnach

125

Jak mogę ustawić unikatowe ograniczenia dla dwóch kolumn?

class MyModel extends Migration {
  public function up()
  {
    Schema::create('storage_trackers', function(Blueprint $table) {
      $table->increments('id');
      $table->string('mytext');
      $table->unsignedInteger('user_id');
      $table->engine = 'InnoDB';
      $table->unique('mytext', 'user_id');
    });
  }
}

MyMode::create(array('mytext' => 'test', 'user_id' => 1);
// this fails??
MyMode::create(array('mytext' => 'test', 'user_id' => 2);
user391986
źródło
1
Niestety w dokumentacji Laravel brakuje tego poziomu szczegółowości . Tak łatwo byłoby o tym wspomnieć na marginesie. Takie szczegóły i - na przykład - fakt, że framework zawsze wydaje się zakładać, że każdy stół będzie miał autoinkrementację id, nadają szkieletowi amatorski charakter wokół krawędzi. Czy ja narzekam? :-(
cartbeforehorse

Odpowiedzi:

278

Drugim parametrem jest ręczne ustawienie nazwy unikalnego indeksu. Użyj tablicy jako pierwszego parametru, aby utworzyć unikalny klucz w wielu kolumnach.

$table->unique(array('mytext', 'user_id'));

lub (trochę schludniej)

$table->unique(['mytext', 'user_id']);
Collin James
źródło
1
+1 dzięki za to ... nie jestem pewien, jak mi to brakowało w dokumentacji. Muszę być ślepy: P
OACDesigns
Jakoś przeoczyłem również fakt, że drugim parametrem jest ręczne nazwanie indeksu i miałem automatycznie wygenerowaną nazwę indeksu, która była zbyt długa. Dziękuje! +1
Ciprian Mocanu
1
+1 dla array(). Ponieważ próbowałem bez tablicy i nie zadziałało. czy mogę podać nazwę ograniczenia podczas uruchamiania klucza złożonego za pośrednictwem konstruktora schematu?
Pankaj
Tak, to drugi parametr
Collin James,
7
Wygenerowane nazwy indeksów są w formacie, table_column1_column2...n_uniquejeśli ktoś nie jest pewien. Porzucenie tego unikalnego ograniczenia byłoby wówczas odniesieniem do tego w$table->dropUnique('table_column1_column2...n_unique');
Jonathan
19

Po prostu możesz użyć

$table->primary(['first', 'second']);

Źródła: http://laravel.com/docs/master/migrations#creating-indexes

Jako przykład:

    Schema::create('posts_tags', function (Blueprint $table) {

        $table->integer('post_id')->unsigned();
        $table->integer('tag_id')->unsigned();

        $table->foreign('post_id')->references('id')->on('posts');
        $table->foreign('tag_id')->references('id')->on('tags');

        $table->timestamps();
        $table->softDeletes();

        $table->primary(['post_id', 'tag_id']);
    });
İsmail Atkurt
źródło
4
Nie gwarantuje to jednak wyjątkowości, po prostu dodaje indeks złożony. Zwykle nie chcesz, aby ten sam tag był dwukrotnie umieszczany w tym samym poście, więc w tym przypadku lepiej go użyć ->unique().
okdewit
3
@ Fx32 to robi gwarancja niepowtarzalności, ponieważ tworzy kompozytowy klucz podstawowy (co jest indeksowane). Jednak nadal zgadzam się, że ->unique()jest to bardziej odpowiednie w tej konkretnej kwestii, ponieważ 'mytext'prawdopodobnie spowodowałoby to zły klucz, jak każdy inny VARCHARlub TEXTkolumna. ->primary([])byłoby świetne do zapewnienia unikalności liczb całkowitych, takich jak klucze obce przestawne.
Jeff Puckett
2
Zwróć również uwagę, że złożone klucze główne są generalnie niezadowolone przez programistów Laravel i nie są one obsługiwane przez Eloquent - patrz github.com/laravel/framework/issues/5355
andrechalom
0
DB::statement("ALTER TABLE `project_majr_actvities`
               ADD UNIQUE `unique_index`(`activity_sr_no`, `project_id`)");
Rajendra Rajput
źródło
ustne wyjaśnienie byłoby pomocne w Twojej odpowiedzi
con