ОШИБКА: идентификатор с разделителями с нулевой длиной на уровне или рядом с "" "" LINE 1: DELETE FROM "region" WHERE "regions". "" = $ 1
Я использую Rails 4.1 и Postgresql (с жемчужиной PG) в качестве моей базы данных. У меня очень много ассоциаций от компаний до провинций с таблицей объединений, называемой регионами. Теперь, очевидно, таблица регионов не имеет первичной причины, по которой я использовал {: id => false}. Но когда я пытаюсь использовать зависящий от уничтожения или просто просто вызываю уничтожить объект области, я сам получаю эту ошибку:
ERROR: zero-length delimited identifier at or near """"
LINE 1: DELETE FROM "regions" WHERE "regions"."" = $1
Я знаю, что проблема вызвана отсутствием первичного ключа для таблицы регионов. И как ни странно, если я добавлю первичный ключ обратно в таблицу, то разрушение будет прекрасным и без ошибок. Однако, если я удалю первичный ключ из таблицы, ошибка вернется. Я знаю, что это имеет какое-то отношение к postgres, но я не знаю, как это решить, не добавляя столбец первичного ключа в таблицу моих регионов.
Вот фактический запрос
[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
Ответы
Ответ 1
Вам нужны одинарные кавычки, а не двойные кавычки вокруг пустых строк, двойные кавычки - идентификаторы с разделителями, а "" не является значимым идентификатором ".
пытаться:
WHERE 'regions'.'' = $1
или по крайней мере:
WHERE "regions".'' = $1
Ответ 2
Попробуйте установить dependent: :delete_all
.
Пример (не совсем уверен, как вы установили настройку "многие-ко-многим").
# models/region.rb
...
has_many: provinces_regions, depend:: delete_all
has_many: провинции, через:: provinces_regions
...
: destroy/: destroy_all удалит связанные объекты, вызвав их метод destroy, и, таким образом, обратные вызовы (: before_destroy,: after_destroy и т.д.).
: delete/: delete_all удаляет связанные объекты без вызова метода destroy.
Ответ 3
Поскольку ни один из ответов здесь не работал для меня, я думал, что включу мое собственное исправление. Не уверен, что такое перевод для вашего случая использования, но я надеюсь, что суть моей стратегии ясна.
Я тоже использую настраиваемый первичный ключ (uuid). Чтобы удалить запись в моей таблице соединений, я пропустил активную запись для фактического вызова на удаление и вместо этого использовал SQL.
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'] }
Я переписал BucketListPhoto#destroy
чтобы использовать это.
Я попытался перезаписать BuckerListPhoto::ActiveRecord::Query#destroy_all
но не смог успешно передать массив uids (чтобы удалить много с одним запросом).
Ответ 4
На основании ответа Алекса Кэрола, но совершенно другого решения.
Если кто-то сделал:
# models/region.rb
...
has_many :provinces_regions, dependent: :destroy_all
has_many :provinces, through: :provinces_regions
...
и получаю эту проблему, тогда я думаю, вы, вероятно, сделали это:
create_table :provinces_regions, id: false do |t|
t.belongs_to :regions, index: true
t.belongs_to :provinces, index: true
end
Если приведенное выше верно, то Rails пытается использовать id
для запуска обратных вызовов перед уничтожением. Итак, дайте ему id
:
create_table :provinces_regions do |t|
t.belongs_to :regions, index: true
t.belongs_to :provinces, index: true
end
И, таким образом, вы можете продолжать использовать dependent: :destroy_all
и использовать обратные вызовы и другие функции, для которых требуется id
.