你实际上已经问了两个不同的问题。
它们都与 Rails 没有特别的关系,所以我将笼统地回答它们(也是因为我对 Ruby 不太熟悉!)。
如何使用'?'防止 SQL 注入
当您直接在 SQL 语句中使用从程序外部提供的值(用户提供的值)时,就会发生 SQL 注入。例如,假设你有这个伪代码:
sql="SELECT foo FROM bar WHERE name='"+name+"'"
name 可能是一个包含用户输入数据的变量。但是,如果 name 包含单引号 ('),则 SQL 引擎会认为单引号是值的结尾,并继续将变量的其余部分解析为 SQL 文本。
使用占位符(例如'?')可以避免这种情况,因为占位符内的值不需要被引用——占位符的所有内容都被视为值的一部分,不会被解析为SQL ,而不管任何嵌入的引号。
顺便说一下,使用的占位符的实际形式在某种程度上取决于实际使用的数据库引擎和/或客户端框架。本机,Postgresql uses the $1, $2, etc for placeholders。许多框架对此进行了扩展以允许“?”和其他占位符语法。
为什么使用“%#{term}%”而不是仅使用#{term}
SQL ILIKE operator 使用“%”符号作为通配符。如下表达式:
taste ILIKE '%apple%'
将使用不区分大小写的匹配匹配“apple”、“rottenApple”、“applesauce”或任何其他包含“apple”的字符串。
请注意,'%' 符号是 ILIKE 右侧操作数的一部分,在引号内,因此您不能使用这样的占位符:
Candy.where("taste ILIKE %?%", "#{term}")
另一种选择是:
Candy.where("taste ILIKE '%' || ? || '%'", "#{term}")
之所以有效,是因为|| 是连接运算符,因此它将文字值% 与占位符的值连接起来,然后是尾随文字值%。