在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: