web-dev-qa-db-ja.com

エラー: "" ""またはその近くの長さ0の区切り識別子

Rails 4.1とPostgresql(PG gemを使用)をデータベースとして使用しています。地域と呼ばれる結合テーブルを使用して、企業から州への多対多の関連があります。テーブルには主キーの原因はありません{:id => false}を使用しました。

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

この問題は、リージョンテーブルのプライマリキーの不足が原因で発生します。そして奇妙なことに、主キーをテーブルに戻すと、destroyは正常に機能し、エラーは発生しません。ただし、テーブルから主キーを削除すると、エラーが返されます。これは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
20
Steve

空の文字列を二重引用符ではなく一重引用符で囲み、二重引用符で区切られた識別子を作成し、「」は意味のある識別子ではありません。

試してください:

WHERE 'regions'.'' = $1

または少なくとも:

WHERE "regions".'' = $1
19
A-S

代わりにdependent: :delete_allを設定してみてください。

例(多対多の関係がどのように設定されているか完全にはわかりません)。

#models/region.rb
...
has_many:provinces_regions、依存::delete_all
has_many:provinces through::provinces_regions
...

:destroy /:destroy_allは、destroyメソッドを呼び出すことで関連付けられたオブジェクトを削除するため、コールバック(:before_destroy、:after_destroyなど)

:delete /:delete_allは、destroyメソッドを呼び出さずに関連オブジェクトを削除します。

15
Alex Carroll

ここでの答えはどれも役に立たなかったので、カスタム修正を含めると思いました。あなたのユースケースの翻訳が何であるかは分かりませんが、私の戦略の要点が明確であることを願っています。

私も、カスタム主キー(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も上書きしようとしましたが、uidの配列を正常に渡すことができませんでした(1つのクエリで多くを削除するため)。

1
max pleaner

Alex Carolの回答に基づいていますが、完全に異なるソリューションです。

誰かがした場合:

# 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は、破壊する前にidsを使用してコールバックを実行しようとしているので、idを指定します。

create_table :provinces_regions do |t|
  t.belongs_to :regions, index: true
  t.belongs_to :provinces, index: true
end

したがって、引き続きdependent: :destroy_allを使用し、idを必要とするコールバックやその他の機能を使用できます。

0
RWDJ