错误:在"""或""附近的零长度分隔标识符"第1行:删除"区域"WHERE"区域".""= $ 1

Ste*_*eve 21 postgresql ruby-on-rails-4

我使用Rails 4.1和Postgresql(带PG gem)作为我的数据库.从公司到省份,我有一个非常多的联盟,有一个叫做区域的联接表.现在很明显,Regions表没有主键,因为我使用{:id => false}.但是当我尝试使用依赖破坏或只是简单地在区域对象上调用destroy时,我自己得到了这个错误:

 ERROR:  zero-length delimited identifier at or near """"
 LINE 1: DELETE FROM "regions" WHERE "regions"."" = $1
Run Code Online (Sandbox Code Playgroud)

我知道问题是由于缺少Regions表的主键引起的.奇怪的是,如果我将主键添加回表中,则销毁工作正常并且没有错误.但是,如果我从表中删除主键,则会返回错误.我知道这与postgres有关但我不知道如何解决这个问题而不必在我的Regions表中添加主键列.

这是实际的查询

[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
Run Code Online (Sandbox Code Playgroud)

A-S*_*A-S 19

您希望单引号不是空字符串周围的双引号,双引号是分隔标识符,而""不是有意义的标识符.

尝试:

WHERE 'regions'.'' = $1
Run Code Online (Sandbox Code Playgroud)

或至少:

WHERE "regions".'' = $1
Run Code Online (Sandbox Code Playgroud)


小智 15

请尝试设置dependent: :delete_all.

示例(不完全确定如何设置多对多关系).

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

:destroy /:destroy_all将通过调用它们的destroy方法删除关联的对象,从而回调(:before_destroy,:after_destroy等)

:delete /:delete_all将删除关联的对象而不调用其destroy方法.


RWD*_*WDJ 7

基于 Alex Carol 的回答,但完全不同的解决方案。

如果有人这样做:

# models/region.rb
...
has_many :provinces_regions, dependent: :destroy_all
has_many :provinces, through: :provinces_regions
...
Run Code Online (Sandbox Code Playgroud)

并且遇到这个问题,那么我猜你可能是这样添加的id: false

create_table :provinces_regions, id: false do |t|
  t.belongs_to :regions, index: true
  t.belongs_to :provinces, index: true
end
Run Code Online (Sandbox Code Playgroud)

如果上述情况属实,那么 Rails 会尝试id在销毁之前使用s 运行回调。所以,给它一个id

create_table :provinces_regions do |t|
  t.belongs_to :regions, index: true
  t.belongs_to :provinces, index: true
end
Run Code Online (Sandbox Code Playgroud)

因此,您可以继续使用dependent: :destroy_all和使用回调和其他需要id.

在这个阶段,您需要进行新的迁移来纠正它。因此,正如侯赛因所说,您应该进行迁移:

add_column :provinces_regions, :id, :primary_key
Run Code Online (Sandbox Code Playgroud)

请参阅此处了解更多详情。

  • 这解决了我的问题。我必须在联合表上添加 `add_column :table_name, :id, :primary_key` 才能使用 `destroy_all`。更多详细信息请参见:https://github.com/rails/rails/issues/25347 (2认同)