2012-03-14 168 views
35

我有一个名为Topic的模型,名称为字段。Rails:如何查找包含特定字符串的字段

所以说我有一个术语,我正在寻找,苹果。

如果我做了

Topic.find_by_name("apple") 

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

编辑: 感谢您的所有答复。我想我应该早一点清楚一点,但是如果我想通过变量名找到(显然我不想每次都想用名称“apple”查找:))?

如何操作Topic.where以适应此? 所以像...

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

添加编辑我的答案与你的最新的编辑,让我知道是否有帮助! – Deleteman 2012-03-14 19:59:54

+0

查看我对@ Alisher的回答的评论,以回答您编辑的问题。 'Topic.where(“name like?”,“#{@ name}%”)将是一种方式。 – 2012-03-14 20:02:25

回答

82

我觉得这样的事情应该工作:

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

,以适应您的编辑:

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

基本串插,你使用@search的值在字符串%%里面,所以你@search = "apple"然后你最后用%apple%

+1

你认为这种方法导致SQL注入吗? – 2015-05-13 19:42:24

+2

据我可以告诉[这里](http://rails-sqli.org/)'where'方法什么都不防止SQL注入。然而,问题con只能通过考虑该变量是否暴露于用户输入,或者通过存储的未经处理的值或直接暴露来回答。这应该是利益问题。对付SQL注入的最好方法是在应用程序进入时清理值,即使在存储之前也是如此。 – GKnight 2015-11-08 00:37:33

+0

如何不包含某个字符串? – zx1986 2017-02-15 08:17:40

0

尝试

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

第一个例子中的SQL注入应该是'Topic.where(“name like?”,“%apple%”)'。第二个确定。 – 2012-03-14 19:48:11

+0

你是对的。 – asitmoharna 2012-03-14 19:50:39

+0

你也可以在Rails 4+中做到这一点:'Topic.find_by(“name like?”,“%apple%”)' – 2017-03-15 17:23:46

9

看起来像Rails 3你想使用其中:

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

不知道这是否会奏效 - 是“〜=”有效的sql吗?还是你在考虑ruby模式匹配器“=〜”。如果是这样,它不会在这里工作,因为它不是sql – 2012-03-14 19:19:18

+0

是的,我注意到,在我引用的文章中,只是把它作为面值...我将改变为LIKE并且安全。谢谢! – ScottJShea 2012-03-14 19:20:38

+5

'〜='运算符适用于PostgreSQL - 这是一个正则表达式匹配。但是,斯科特的回答应该有效。您可能想要使用ILIKE,它会提供不区分大小写的搜索。 – 2012-03-14 19:42:53

7

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

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

这应该是“名称像”?%'“或”名称像'%?%'“ – varatis 2012-03-14 19:35:55

+3

这不会像指出的那样工作,因为Rails会自动引用字符串。你需要在替换之前加上'%',例如'Topic.where(“name like?”,“#{params [:name]}%”)。' – 2012-03-14 19:58:41

+0

很好的答案。 – 2016-04-16 16:04:59

2

在PostgreSQL,您还可以使用match operators

Topic.where("name ~* ?", @search) 
相关问题