将postgres hstore sql转换为Arel

时间:2012-10-11 12:44:05

标签: ruby-on-rails arel hstore

我在名为hstore的{​​{1}}表中有一个users列。

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

properties

我试过了:

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

这会产生错误的sql:

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

与我需要的相比:

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

2 个答案:

答案 0 :(得分:13)

您可以通过创建自己的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'

如果您从未听说过中缀符号,Wikipedia gives a good explaination

  

Infix表示法是常用的算术和逻辑公式表示法,其中运算符在它们作用的操作数之间写入中缀式(例如2 + 2)。通过计算机解析前缀表示法(例如+ 2 2)或后缀表示法(例如2 2 +)并不是那么简单,但许多编程语言因其熟悉而使用它。

不幸的是,Arel没有太多文档,InfixOperation节点也没有,因此开始时可能会令人沮丧。当您在寻找如何使用Arel执行特定的SQL操作时,最好的办法是查看the nodes directory in the source code

答案 1 :(得分:-2)

如果你使用activerecord-postgres-hstore宝石,你将能够:

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的优秀示例代码。