2015-12-13 11 views
5

Próbuję zrobić 2 pola unikalne ograniczenie w Ecto Postgres. Do tej pory udało mi się zrobić:unique_constraint na 2 polach nie są rozpoznawane

migracji:

create unique_index(:presences, [:event_id, :user_id], name: :special_event_user) 

changeset:

def changeset(presence, params \\ :empty) do 
    presence 
     |> cast(params, @required_fields, @optional_fields) 
     |> foreign_key_constraint(:user_id) 
     |> foreign_key_constraint(:event_id) 
     |> unique_constraint(:event_id, name: :special_event_user) 
    end 

Próbowałem również:

|> unique_constraint(:special_event_user) 

ale wciąż otrzymuję:

If you would like to convert this constraint into an error, please 
call unique_constraint/3 in your changeset and define the proper 
constraint name. The changeset has not defined any constraint. 

Co myślałem, że już zrobiłem. Jakieś sugestie?

Edit:

Działanie:

def assign(conn, %{"event" => event_id}) do 
    case Integer.parse(event_id) do 
     {val, _ } -> 
      case Repo.one(User.unique_user(User, get_session(conn, :login))) do 
      nil -> conn 
       |> put_flash(:error, "Błąd bazy danych") 
       |> redirect(to: "/event") 
      result -> 
       presence = %Presence{ user_id: result.id, event_id: val, state: Presence.get_assigned } |> Repo.insert! 
       conn 
       |> put_flash(:info, "Zostałeś zapisany na wydarzenie") 
       |> redirect(to: "/event") 
      end 
    end 
    end 

Egzample obecność z powyższym kodem, gdy nie ma błędu:

%Kpsz.Model.Presence{__meta__: #Ecto.Schema.Metadata<:loaded>, 
event: #Ecto.Association.NotLoaded<association :event is not loaded>, 
event_id: 1, id: 1, inserted_at: #Ecto.DateTime<2015-12-14T15:45:39Z>, 
state: 1, updated_at: #Ecto.DateTime<2015-12-14T15:45:39Z>, 
user: #Ecto.Association.NotLoaded<association :user is not loaded>, user_id: 1} 

Edit: Teraz dostaję:

constraint error when attempting to insert model: 

    * unique: special_event_user 

If you would like to convert this constraint into an error, please 
call unique_constraint/3 in your changeset and define the proper 
constraint name. The changeset defined the following constraints: 

    * unique: presences_special_event_user_index 
    * foreign_key: presences_event_id_fkey 
    * foreign_key: presences_user_id_fkey 
+2

Twoja definicja wydaje się dopasować przykład w dokumentacji ekto. Spróbuj przekazać nazwę indeksu bezpośrednio do ograniczenia tak, jak to zrobiono w tym [blogu] (http://blog.praveenperera.com/using-compound-unique-indexes-to-validate-uniqueness-of-ecto-associations) , czyli 'unique_constraint (: special_event_user)' – AbM

+0

To samo dla mnie ... – Haito

+1

Czy możesz podać kod, którego używasz do utworzenia rekordu? – Gazler

Odpowiedz

7

Nie zamierzasz thr za pomocą funkcji zmiany zestawu.

presence = 
    %Presence{ user_id: result.id, event_id: val, state: Presence.get_assigned } 
    |> Repo.insert! 

Powinno być:

presence = 
    Presence.changeset(%Presence{), %{user_id: result.id, event_id: val, state: Presence.get_assigned}) 
    |> Repo.insert! 
+1

No cóż .. bezmyślne kopiowanie czasami jest bolesne. Dziękuję bardzo za poświęcony czas panu. – Haito

+0

Czy mógłbyś jeszcze raz spojrzeć na dół głównego postu? Dostaję kolejny dziwny błąd. Wciąż mi mówi, że nie nazwałem tej funkcji. Ale tym razem podpowiada nazwę wywoływanych funkcji, gdzie jeden jest bardzo podobny do tego, którego użyłem. – Haito

+0

Jeśli masz błąd ograniczenia i użyjesz 'Repo.insert!' Zamiast 'Repo.insert', to podniesie. Czy to możliwe, co się dzieje? – Gazler