3

hstoreusers表中有一个名为properties.

如何将 where 条件中的静态 sql 字符串转换为 aRel 语法?

User.where("properties -> 'is_robber' = 'true'") #=> ...some users

我试过了:

ut = User.arel_table
condition = ut["properties -> 'is_robber'"].eq('true')
User.where(condition) #=> throws pg error

这会产生错误的sql:

 SELECT "users".* FROM "users" WHERE "users"."properties -> 'is_robber'" = 'true'

与我需要的相比:

SELECT "users".* FROM "users" WHERE "users".properties -> 'is_robber' = 'true'
4

2 回答 2

14

您可以通过创建自己的 Arel::Nodes::InfixOperation 来使用 Arel 完成此操作:

ut = Arel::Table.new(:user)
hstore_key = Arel::Nodes::InfixOperation.new("->", ut[:properties], 'is_robber')
User.where(hstore_key.eq('true'))

将产生:

SELECT "users".* FROM "users" WHERE "users"."properties" -> 'is_robber' = 'true'

如果您从未听说过中缀表示法,维基百科给出了很好的解释

中缀表示法是常见的算术和逻辑公式表示法,其中运算符在它们作用的操作数之间以中缀样式编写(例如 2 + 2)。计算机解析它不像前缀表示法(例如 + 2 2 )或后缀表示法(例如 2 2 + )那么简单,但是由于它的熟悉性,许多编程语言都使用它。

不幸的是,没有太多关于 Arel 的文档,也没有关于 InfixOperation 节点的文档,因此一开始可能会令人沮丧。当您在寻找如何使用 Arel 执行特定 SQL 操作时,最好的办法是查看源代码中的节点目录

于 2013-11-27T09:04:10.510 回答
-2

如果您使用activerecord-postgres-hstore gem,您将能够:

class User < ActiveRecord::Base
  serialize :data, ActiveRecord::Coders::Hstore
end

User.where("data -> 'speed' = 'ludicrous'")

更多信息:
* https://github.com/softa/activerecord-postgres-hstore
* http://railscasts.com/episodes/345-hstore

RailsCast Pro 集有关于自动创建范围、getter 和 setter 的优秀示例代码。

于 2012-10-11T13:29:54.277 回答