我正在尝试一些概念(实际上通过构建1978年数据库WHRSIT的RoR版本来玩和学习?)。
它基本上是一个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 :(得分:0)
您的代码需要注意的事情......
我第一次尝试重构你的代码就是看看Arel是否可以做到这一点。或者是Sequeel,或者他们称之为" metawhere"宝石这几天。我的第二次尝试将是这样的:
arrel.where( [ bracket_array.size.times.map{"#{name} ILIKE ?"}.join(' OR '), *bracket_array ])
我没有测试它,但想法是使用bracket_array的大小生成一串OR条件,然后使用splat运算符传入所有值。
答案 1 :(得分:0)
感谢Phillip指出我正确的方向。
[儿子,女儿]的东西只是一个控制台练习,看看我能做什么,但不知道我将用它做什么。我最终获得了模型关联并从图片中创建了数组并实现了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
这些东西只是为了展示steve son|daughter
=>显示孩子phone james%|lori%
=>显示任何名字以james或lori开头的人的电话号码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类来处理解析和搜索的学习练习。
史蒂夫