Schema Builder Laravel migraciones únicas en dos columnas


125

¿Cómo puedo establecer restricciones únicas en dos columnas?

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


1
Este nivel de detalle lamentablemente falta en los documentos de Laravel . Sería tan fácil mencionarlo de pasada. Detalles como este y, por ejemplo, el hecho de que el marco siempre parece suponer que cada tabla va a tener un incremento automático id, le da al marco una sensación de aficionado en los bordes. ¿Estoy despotricando? :-(
cartbeforehorse

Respuestas:


277

El segundo parámetro es establecer manualmente el nombre del índice único. Use una matriz como primer parámetro para crear una clave única en varias columnas.

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

o (un poco más ordenado)

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

1
+1 gracias por esto ... no estoy seguro de cómo me lo perdí en la documentación. Debo ser ciego: P
OACDesigns

También de alguna manera me perdí el hecho de que el segundo parámetro es nombrar manualmente el índice y tenía un nombre de índice generado automáticamente que era demasiado largo. ¡Gracias hombre! +1
Ciprian Mocanu

1
+1 para array(). Porque lo intenté sin matriz y no funcionó. ¿puedo dar un nombre de restricción mientras ejecuto la clave compuesta a través del generador de esquemas?
Pankaj

Sí, ese es el segundo parámetro
Collin James

77
Los nombres de índice generados están en el formato table_column1_column2...n_uniquesi alguien no está seguro. Dejar caer la restricción única sería hacer referencia a eso en$table->dropUnique('table_column1_column2...n_unique');
Jonathan

19

Simplemente puedes usar

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

Referencia: http://laravel.com/docs/master/migrations#creating-indexes

Como ejemplo:

    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']);
    });

44
Sin embargo, esto no garantiza la unicidad, solo agrega un índice compuesto. Por lo general, no desea la misma etiqueta dos veces en la misma publicación, por lo que para este caso de uso es mejor usarla ->unique().
okdewit

3
@ Fx32 esto hace singularidad de garantía, ya que crea un compuesto clave principal (que está indexado). Sin embargo, todavía de acuerdo en que ->unique()es más apropiado en esta cuestión específica, porque 'mytext'probablemente haría una mala clave como lo haría cualquier VARCHARo TEXTcolumna. ->primary([])sería excelente para garantizar la unicidad en los enteros, como las claves externas de pivote.
Jeff Puckett

2
Observe también que las claves primarias compuestas son generalmente mal visto por los desarrolladores laravel, y que no son compatibles con elocuente - ver github.com/laravel/framework/issues/5355
andrechalom

0
DB::statement("ALTER TABLE `project_majr_actvities`
               ADD UNIQUE `unique_index`(`activity_sr_no`, `project_id`)");

una explicación verbal sería una adición útil a su respuesta
con
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.