2014-04-19 12 views
11

Używam Rails 4.1 i Postgresql (z gemem PG) jako moją bazą danych . Mam bardzo wiele stowarzyszeń, od firm po prowincje połączone tabelą regionów. Oczywiście tabela regionów nie ma klucza głównego, bo użyłem {: id => false}. Ale gdy próbuję użyć zależności zniszczyć lub po prostu dzwoniąc zniszczyć w regionie obiekt to samo mi ten błąd:BŁĄD: wyodrębniony identyfikator o zerowej długości w lub w pobliżu "" "LINE 1: DELETE FROM" regiony "GDZIE" regiony "." "= 1

ERROR: zero-length delimited identifier at or near """" 
LINE 1: DELETE FROM "regions" WHERE "regions"."" = $1 

Znam problem jest spowodowany z powodu braku klucza podstawowego dla tabeli regionów. I dziwnie, jeśli dodaję klucz podstawowy z powrotem do stołu, niszczą działa dobrze i nie ma błędów. Jeśli jednak usunę klucz podstawowy z tabeli, pojawi się błąd. Wiem, że ma to coś wspólnego z postgres, ale nie mam pojęcia, jak rozwiązać ten problem bez konieczności dodawania kolumny klucza podstawowego do mojej tabeli regionów.

Oto rzeczywistego zapytania

[DEBUG] [AdminUser Load (0.4ms) SELECT "admin_users".* FROM "admin_users" WHERE "admin_users"."id" = 1 ORDER BY "admin_users"."id" ASC LIMIT 1] (pid:29655) 
[DEBUG] [Province Load (0.2ms) SELECT "provinces".* FROM "provinces" WHERE "provinces"."id" = $1 LIMIT 1 [["id", 5]]] (pid:29655) 
[DEBUG] [ (0.1ms) BEGIN] (pid:29655) 
[DEBUG] [Region Load (0.3ms) SELECT "regions".* FROM "regions" WHERE "regions"."province_id" = $1 [["province_id", 5]]] (pid:29655) 
[ERROR] [PG::SyntaxError: ERROR: zero-length delimited identifier at or near """" 
LINE 1: DELETE FROM "regions" WHERE "regions"."" = $1 
+0

Będziesz musiał wyświetlić rzeczywiste zapytanie SQL wygenerowane przez Rails; możesz go pobrać z plików dziennika PostgreSQL lub z logów Rails. –

+4

To: 'WHERE" regiony "." "= 1 $" jest nieprawidłowym SQL i to nie jest wina PostgreSa - to Railsy, ​​które tworzą niepoprawny SQL. Domyślam się, że Railsy generują warunek 'where' oparty na kolumnach, które składają się na klucz podstawowy. Ponieważ nie ma takich kolumn, wygenerowano nieprawidłowy kod SQL (zasadniczo używając pustej nazwy kolumny). –

+1

Tak, masz rację. samego siebie.primary_key =: province_id rozwiązuje problem, ale nie jest on najczystszy ... – Steve

Odpowiedz

10

spróbuj ustawić dependent: :delete_all zamiast.

Przykład (Nie jestem do końca pewien, w jaki sposób skonfigurowano wiele relacji między wieloma osobami).

# models/region.rb
...
has_many :provinces_regions, dependent: :delete_all
has_many :provinces, through: :provinces_regions
...

: zniszczyć /: destroy_all usunie skojarzone obiekty wywołując metodę ich zniszczyć, a tym samym wywołania zwrotne (: before_destroy: after_destroy, etc.)

: usuwanie /: delete_all usunie powiązane obiekty bez wywoływania metody niszczenia.

+0

z 'has_many [ ...] poprzez "to działa. Nie znalazłem odniesienia w tym przewodniku szyn ... – Jerome

+0

działa w szynach 3.2 – Jerome

+0

to nie działa dla mnie. ten sam błąd. szyny 4.2 –

7

Chcesz pojedynczych cudzysłowów, a nie podwójnych cudzysłowów wokół pustych ciągów, podwójne cudzysłowy zrobić rozgraniczone identyfikatory, a "" nie jest znaczącym identyfikatorem.

try:

WHERE 'regions'.'' = $1 

lub co najmniej:

WHERE "regions".'' = $1 
1

Ponieważ żadna z odpowiedzi tutaj pracował dla mnie, myślałem, że to mój własny poprawkę. Nie jestem pewien, jakie jest tłumaczenie dla twojego przypadku użycia, ale mam nadzieję, że sedno mojej strategii jest jasne.

Ja też używam niestandardowego klucza podstawowego (uuid). Aby usunąć rekord z mojej tabeli join, pominąłem aktywny rekord dla rzeczywistego wywołania delete i użyłem SQL zamiast tego.

uid = BucketListPhoto.find_by(bucket_list_id: 12, photo_id: 4).uid 

deleted_uids = ActiveRecord::Base.connection.execute(
    "DELETE FROM bucket_list_photos WHERE uid='#{uid}' RETURNING uid" 
).to_a.map { |record| record['uid'] } 

Wpisuję BucketListPhoto#destroy, aby użyć tego.

Próbowałem również nadpisać BuckerListPhoto::ActiveRecord::Query#destroy_all, ale nie udało mi się pomyślnie przejść przez tablicę identyfikatorów (aby usunąć wiele z jednym zapytaniem).

Powiązane problemy