0

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

它基本上是一个 has_many :through 结构,主题 -> 标签 <- 值。我尝试通过使用查询文本字段输入命令来复制一些命令行结构。基本上是这样的: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]')产生like子句tags.name ILiKE 'son' OR tags.name ILiKE 'daughter'

它得到了关系,但在所有关于使用表格的讨论中 ("tags.name ILiKE ? OR tags.name ? ",v1,v2,vN..),我想问是否有人对如何做到这一点有任何想法。

根据我的搜索,动态创建变量是可行的,但不赞成。我只是想知道是否有人尝试过创建可以添加具有可变编号参数的 where 子句的方法。我尝试将 where 子句发送到关系,但它不喜欢那样。

史蒂夫

4

2 回答 2

0

在您的代码中需要注意的几件事......

  • 当括号数组的元素之一包含单引号时会发生什么?
  • 如果我更进一步并设置一个元素说“'; drop tables...”会发生什么?

我重构代码的第一个尝试是看看 Arel 是否可以做到。或者续集,或者这些天他们所谓的“metawhere”宝石。我的第二次刺是这样的:

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

我没有测试它,但想法是使用bracket_array的大小来生成一串OR'd条件,然后使用splat运算符传入所有值。

于 2012-12-31T20:55:04.093 回答
0

感谢菲利普为我指明了正确的方向。

  • 我不知道您可以将数组传递给 where 子句 - 这打开了一些选项
  • 我使用了几次 splat 运算符,但它实际上创建了一个对象(变量)并没有让我感到震惊

[儿子,女儿] 的东西只是一个控制台练习,看看我能做什么,但不知道我会用它做什么。我最终采用了模型关联并从图片中创建了数组并实现了 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 类来处理解析和搜索的学习练习。

史蒂夫

于 2013-01-01T23:20:55.557 回答