2016-04-05 7 views

Antwort

43

sich ein wenig auf die Antwort von Patrick folgen

nur auf Ihrem Modell verwenden erstellen unique_index wird letztlich eine Ausnahme werfen, anstatt Sie einen Fehler geben.

Um einen Fehler zu erhalten, fügen Sie eine Einschränkung für Ihren Änderungssatz hinzu, aber als Parameter können Sie den Indexnamen angeben, der von unique_index erstellt wurde.

Also in Ihrer Migrationsdatei:

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

Dann in Ihrem 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

Dies sollte als akzeptierte Antwort imo markiert werden. @TheSquad, hat: Name_Ihr_Constraint muss entweder sein: Col1 oder: Col2 in diesem Zusammenhang? Referenz: https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3 – Olshansk

+1

absolut nicht, können Sie jedes Atom, das Sie möchten, eine umfassende Fehlermeldung haben, wenn die Einschränkung nicht erfüllt ist – TheSquad

10

Sie können mit

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

ich einen eindeutigen Index auf mehrere Zeilen erstellen nehme an, wenn Sie zusammengesetzte Schlüssel haben wollen, müssen Sie execute/1 benutzen, um Ihre SQL manuell ausführen. Nicht sicher, wie gut zusammengesetzte Schlüssel mit Ecto funktionieren, ich bleibe jedoch im Allgemeinen bei der Standard-Serien-ID pro Tabelle.

Wenn Sie mit dem Composite-Key-Ansatz gehen sollten, denke ich, dass die NOT NULL Einschränkungen nicht notwendig sind. Der zusammengesetzte Schlüssel sollte bereits erzwingen, dass die Spalten nicht null sind.

4

unique_index würde nicht einen zusammengesetzten Primärschlüssel erstellen, wie in dem Beispiel der Frage gezeigt. Es erzeugt eine einzigartige Einschränkung.

Wenn Sie einen zusammengesetzten Primärschlüssel erstellen wollen (beachten Sie: nicht zu empfehlen, wenn sie mit Ecto arbeiten), there's more information here:

Migration:

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 
    ... 

In den meisten Fällen ist unique_index aber was Sie wollen.