如何控制ActiveRecord在构建查询时是否使用$ 1,$ 2 ..占位符?

时间:2014-07-10 15:02:24

标签: ruby-on-rails postgresql activerecord prepared-statement

我的User模型有两个属性community_id(整数)和remote_id(字符串)。

当我运行User.where(community_id: 1, remote_id: 'abc')时,我会在日志中看到以下查询:

SELECT "users".* FROM "users" WHERE "users"."community_id" = $1 AND
  "users"."remote_id" = 'abc' [["community_id", 1]]

为什么ActiveRecord使用$1的{​​{1}}占位符,但community_id不使用$2

似乎因为它没有使用占位符,AR会为remote_id的每个值生成不同的预准备语句。这填补了准备好的陈述,可能会导致冲突。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

我最终找到了一种方法来强迫" ActiveRecord使用占位符,使用带有列绑定的find_by_sql

columns = User.connection.schema_cache.columns_hash("users")

User.find_by_sql("SELECT * FROM users WHERE community_id = $1 AND remote_id = $2 LIMIT 1",
  [[columns["community_id"], 1], [columns["remote_id"], "abc"]])

导致以下准备声明:

SELECT * FROM users WHERE community_id = $1 AND remote_id = $2 LIMIT 1 [["community_id", 1], ["remote_id", "abc"]]

现在所有查询都使用相同的语句,具有不同的参数。

我不知道是否有更好/更优雅的方式来获取AR列定义,而不是来自schema_cache,但这可以完成工作。