Rails:如何通过包含特定字符串的字段进行find_by


75

我有一个名为Topic的模型,该模型具有一个名称作为字段。

所以说我有一个要搜索的术语,苹果。

如果我做一个

Topic.find_by_name("apple")

我得到一个苹果名字的记录。很好-但是如何更改find​​_by_name以便它既可以找到“ apple juice”又可以找到“ apple”-基本上是找到包含原始查询或与原始查询完全匹配的名称?

编辑: 感谢您的所有答复。我想我本来应该更清楚一点,但是如果我想用一个变量名来查找(显然,我不想每次都用“ apple”这个名字来查找:))怎么办?

我如何操纵Topic.where来适应这一点?所以像...

@topic = Topic.where(......., @name)

在与您的最新编辑相关的答案中添加了一个编辑,请告诉我是否有帮助!
Deleteman 2012年

请参阅我对@Alisher答案的评论,以获取对已编辑问题的答案。 Topic.where("name like ?","#{@name}%")将是一种方式。
汤姆·哈里森

Answers:


147

我认为这样的事情应该起作用:

Topic.where("name like ?", "%apple%")

为了适应您的编辑:

Topic.where("name like ?", "%#{@search}%")

基本的字符串插值,您使用的@search是字符串内部的值%%,因此@search = "apple"最终得到 %apple%


2
您是否认为此方法导致SQL注入?
阿斯温·拉玛克里希南

2
据我所知where方法无法防止SQL注入。但是,只有通过考虑该变量是否曾经通过存储的未经过消毒的值或直接通过用户输入暴露,才能真正回答问题。那应该是感兴趣的问题。对抗SQL注入的最佳方法是在应用程序进入甚至存储之前就清理值。
GKnight

不包含某个字符串怎么办?
zx1986 '17

3
只要使用?,Rails就会阻止SQL注入。如上所示的参数。如果您改用“像%@ search%之类的名字”,则会保持开放状态。
bkunzi01年



10

Rails 3中,您似乎需要使用where:

Topic.where("name ILIKE ?", "%apple%")

1
不知道这是否行得通-是~~有效的sql吗?还是您在考虑红宝石模式匹配器“ =〜”。如果是这样,它就不能在这里工作了,因为它不是sql
Michael Durrant

是的,我注意到在我引用的帖子中,只是以表面的价值看待它...我将改为喜欢,并且很安全。谢谢!
ScottJShea 2012年

5
~=运算符适用于PostgreSQL-这是一个正则表达式匹配项。但是,是的,斯科特的答案应该起作用。您可能要使用ILIKE,它提供不区分大小写的搜索。
汤姆·哈里森

9

不要像这样直接放置字符串。它称为SQL注入。您应该改用.where

Topic.where("name like '?%' ", params[:name])

应该是“像'?%'之类的名称”还是“像'%?%'之类的名称”
varatis 2012年

3
这将无法完全按照说明的方式工作,因为Rails会自动引用该字符串。您需要%在替换前加注,例如Topic.where("name like ?", "#{params[:name]}%").
Tom Harrison

漂亮的答案。😎
马里奥Zigliotto

2

尝试

Topic.where("name like ?",'%apple%')
Topic.find(:all, :conditions => ["name like ?","%apple%"])

第一个示例中的SQL注入应为Topic.where("name like ?","%apple%")。第二个人没关系。
汤姆·哈里森

2
您也可以在Rails 4+中做到这一点:Topic.find_by("name like ?", "%apple%")
保罗·怀特黑德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.