我在名为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'
答案 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的优秀示例代码。