2016-04-05 11 views

risposta

43

A Little follow-up sulla risposta di Patrick

Utilizzando solo creare unique_index del modello in ultima analisi, un'eccezione invece di dare voi un errore.

Per ottenere un errore, aggiungere un vincolo sul set di modifiche ma, in qualità di misuratore, è possibile fornire il nome dell'indice creato da unique_index.

Quindi nel tuo file di migrazione:

create unique_index(:your_table, [:col1, :col2], name: :your_index_name) 

Poi, nel tuo changeset:

def changeset(model, param \\ :empty) do 
    model 
    |> cast(params, @required_fields, @optional_fields) 
    |> unique_constraint(:name_your_constraint, name: :your_index_name) 
end 
+0

Questo dovrebbe essere contrassegnato come la risposta accettata imo. @TheSquad, fa: name_your_constraint deve essere o: col1 o: col2 in questo contesto? Riferimento: https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3 – Olshansk

+1

assolutamente no, puoi mettere qualsiasi atomo per cui vuoi avere un messaggio di errore completo quando il vincolo non è soddisfatto – TheSquad

10

è possibile creare un indice univoco su più righe con

create unique_index(:some_table, [:col1, :col2]) 

Suppongo che se si vuole avere chiavi composte, è necessario utilizzare execute/1 per eseguire SQL manualmente. Non sono sicuro del modo in cui le chiavi composite funzionano con Ecto, ma in genere mi limito a utilizzare l'ID seriale standard per tabella.

Se si deve seguire l'approccio con chiave composita, penso che i vincoli NOT NULL non siano necessari. La chiave composita dovrebbe già applicare che le colonne non siano nulle.

4

unique_index sarebbe non creare una chiave primaria composta come mostrato nell'esempio della domanda. Crea un vincolo unico.

Se si vuole creare una chiave primaria composta (nota: non consigliato quando si lavora con Ecto), there's more information here:

Migrazione:

defmodule HelloPhoenix.Repo.Migrations.CreatePlayer do 
    use Ecto.Migration 

    def change do 
    create table(:players, primary_key: false) do 
     add :first_name, :string, primary_key: true 
     add :last_name, :string, primary_key: true 
     add :position, :string 
     add :number, :integer 
     ... 

schema:

defmodule HelloPhoenix.Player do 
    use Ecto.Schema 

    @primary_key false 
    schema "players" do 
    field :first_name, :string, primary_key: true 
    field :last_name, :string, primary_key: true 
    field :position, :string 
    field :number, :integer 
    ... 

Nella maggior parte dei casi, unique_index è ciò che si desidera, comunque.

Problemi correlati