在Rails的Arel中发生了PostgreSQL Syntax错误

如果在Rails中使用Arel发出SQL查询,当使用PostgreSQL版本9.2时会出现错误。而在9.4版本下不会出错。
由于在使用的CI服务上的PostgreSQL版本不同,可能会导致在本地不会出错的情况下在CI上出错,这会导致混乱,所以做个备忘录。

错误内容 (yuè wù

ActiveRecord::StatementInvalid:
       PG::SyntaxError: ERROR:  syntax error at or near "FROM"
       LINE 1: ...ions".* FROM "reservations" WHERE (EXISTS (SELECT FROM "stor...
                                                                    ^
       : SELECT "reservations".* FROM "reservations" WHERE (EXISTS (SELECT FROM "stored_reservations" WHERE "reservations"."id" = "stored_reservations"."id"))

在Rails的模型中使用scope

我之前的描述如下所示。

  scope :exists_in_stored, -> do
    arel_stored_reservations = Stored::Reservation.arel_table

    condition = reservations[:id].eq(arel_stored_reservations[:id])
    where(arel_stored_reservations.where(condition).exists)
  end

SQL是用于管理关系数据库的编程语言。

Scope中包含以下SQL查询。

SELECT "reservations".* 
FROM "reservations" 
WHERE (EXISTS (
    SELECT FROM "stored_reservations" 
    WHERE "reservations"."id" = "stored_reservations"."id")
)

导致的原因是什么?

当在EXISTS的内部SELECT之后出现FROM时,会导致语法错误。
在PostgreSQL版本为9.2的情况下会出现错误。

解决方案 cè)

将scope的描述更改为以下内容。

  scope :exists_in_stored, -> do
    arel_stored_reservations = Stored::Reservation.arel_table

    condition = reservations[:id].eq(arel_stored_reservations[:id])
    where(Stored::Reservation.where(condition).exists)
  end

那么,SQL会变成下面这样。

SELECT "reservations".* 
FROM "reservations" 
WHERE (EXISTS (
    SELECT "stored_reservations".* FROM "stored_reservations" 
    WHERE "reservations"."id" = "stored_reservations"."id")
)

这样的话,即使在PostgreSQL9.2中也不会出错。

顺便提一下,在wercker上指定PostgreSQL版本的方法是在wercker.yml文件中按照以下方式进行描述。

wercker.yml 的含义是什么?

box: wercker/rvm
no-response-timeout: 10

services:
    # 使用できるserviceを検索するには以下を参照
    # https://app.wercker.com/#explore/boxes/search/ 
    #- wercker/postgresql
    #- wercker/postgresql@0.0.4
    - wercker/postgresql9.2@0.0.7
    #- bolek-kurowski/postgresql9.3@0.0.8
    #- userminddeployer/postgresql9.3@0.0.7-usermind-9.3-1
    #- userminddeployer/postgresql9.4@0.0.7-usermind-9.4-3

    #- wercker/redis@1.0.1
    - wercker/redis
build:
    steps:
      - rvm-use:
广告
将在 10 秒后关闭
bannerAds