2012-12-31 13 views
0

我正在试验一些概念(实际上是通过构建1978年数据库WHATSIT的RoR版本来玩和学习)。从数组构建ILIKE子句

它基本上是一个has_many:通过结构与主题 - >标签< - 价值。我试图通过使用查询文本字段来输入命令来复制一些命令行结构。基本上是这样的:What's steve's phone

总之,大多数搜索使用ILIKE。我虽然通过允许OR条件使用某种形式的数组来增强它。像What's steve's [son,daugher]。我通过直接创建ILIKE子句来实现它,但不能用字符串替换。

def bracket_to_ilike(arrel,name,bracket) 
    bracket_array = bracket.match(/\[([^\]]+)\]/)[1].split(',') 
    like_clause = bracket_array.map {|i| "#{name} ILiKE '#{i}' "}.join(" OR ") 
    arrel.where(like_clause) 
end 

bracket_to_ilike(tags,'tags.name','[son,daughter]')产生类似条款tags.name ILiKE 'son' OR tags.name ILiKE 'daughter'

而且它得到了关系,但所有人都在谈论使用形式("tags.name ILiKE ? OR tags.name ? ",v1,v2,vN..),我以为我会问,如果任何人有如何做任何想法那。

动态创建变量可以从我搜索的内容中获得,但不支持。我只是想知道是否有人试图创建一个方法,可以添加一个具有可变数字参数的where子句。我尝试将where子句发送给关系,但它不喜欢那样。

史蒂夫

回答

0

感谢菲利普指点我在正确的方向。

  • 我不知道,你可以传递一个数组的where子句 - 这开辟了一些选项
  • 我曾用图示操作几次,但它并没有打我,它实际上创造一个对象(变量)

[儿子,女儿]的东西只是一个控制台练习,看看我能做什么,但不知道我会怎么做。我结束了模型关联并创建了阵列,并实现了OR搜索。

def array_to_ilike(col_name,keys) 
    ilike = [keys.map {|i| "#{col_name} ILiKE ? "}.join(" OR "), *keys ] 
    #ilike = [keys.size.times.map{"#{col_name} ILIKE ?"}.join(' OR '), *keys ] 
    #both work, guess its just what you are use to. 
end 

然后我让管道(|)字符在我的题目,标签,值的搜索,所以的whatsit风格问题

  • What's Steve's Phone Home|Work =>显示家庭和工作电话
  • steve phone home|work的“ s的东西只是为了显示
  • steve son|daughter =>显示儿童
  • phone james%|lori% =>显示任何人的姓名电话号码与詹姆斯和洛瑞开始
  • james%|lori% =>转储谁的名字上的任何人的所有信息与詹姆斯或洛瑞开始

然后查询解析命令,如果它遇到|在任何的话,它会做这样的事情:

t_ilike = array_to_ilike('tags.name',name.split("|")) 
# or I actually stored it off on the inital parse 
t_ilike = @tuple[:tag][:ilike] ||= ['tags.name ilike ?',tag] 

再次,这仅仅是一个学习锻炼创建非CRUD类来处理解析和搜索。

史蒂夫

0

几件事情要注意在你的代码...当bracket_array的元素之一包含一个单引号

  • 会发生什么?
  • 如果我更进一步并设置一个元素来说“'; drop tables ...”会发生什么?

我第一次重构你的代码会看看Arel是否可以做到这一点。或者Sequeel,或者他们现在称之为“metawhere”的宝石。我的第二个刺会是这样的:

arrel.where([ bracket_array.size.times.map{"#{name} ILIKE ?"}.join(' OR '), *bracket_array ]) 

我没有测试它,但这个想法是使用bracket_array的大小产生的逻辑与的条件字符串,然后使用图示操作者通过在所有的价值。

+0

你让我更接近,但时间循环返回一个固定的数字,给予和连接错误。回到我的地图循环并使用splat,它给出了类似于子句和变量的权利。起初它给了我一个And子句,但我认为是因为我的标签实例搞砸了。 'tags.where(* [bracket_array.map {| i |“#{name} ILiKE?”} .join(“OR”),* bracket_array])'工作。现在我只需要明白为什么要在哪里取数组参数。这个实验又是为了学习更多的Ruby。 – appleII717

+0

@ appleII717是的,你说得对。我应该有'bracket_array.size.times.map'(缺少.map)。我更新了我的帖子。 –