我正在尝试做这样的类似查询
def self.search(search, page = 1 )
paginate :per_page => 5, :page => page,
:conditions => ["name LIKE '%?%' OR postal_code like '%?%'", search, search], order => 'name'
end
但是当它运行时,某些东西会添加引号,这会导致 sql 语句像这样出现
SELECT COUNT(*)
FROM "schools"
WHERE (name LIKE '%'havard'%' OR postal_code like '%'havard'%')):
所以你可以看到我的问题。我正在使用 Rails 4 和 Postgres 9,我从未使用过这两个版本,所以不确定它是和活动记录的东西还是可能是 postgres 的东西。
如何设置它,以便我在最后查询中具有喜欢'%my_search%'
?
您的占位符被字符串替换,并且您没有正确处理它。
取代
"name LIKE '%?%' OR postal_code LIKE '%?%'", search, search
跟
"name LIKE ? OR postal_code LIKE ?", "%#{search}%", "%#{search}%"
2 中的 conditions
语法,而是使用 Rails 4 的 where
方法:
def self.search(search, page = 1 )
wildcard_search = "%#{search}%"
where("name ILIKE :search OR postal_code LIKE :search", search: wildcard_search)
.page(page)
.per_page(5)
end
注意:上面使用参数语法而不是 ? 占位符:这两者都应该生成相同的 SQL。
def self.search(search, page = 1 )
wildcard_search = "%#{search}%"
where("name ILIKE ? OR postal_code LIKE ?", wildcard_search, wildcard_search)
.page(page)
.per_page(5)
end
注意:使用 ILIKE
作为名称 - LIKE 的不区分大小写版本
虽然字符串插值将起作用,但正如您的问题指定 rails 4 一样,您可以为此使用 Arel 并保持您的应用程序数据库不可知。
def self.search(query, page=1)
query = "%#{query}%"
name_match = arel_table[:name].matches(query)
postal_match = arel_table[:postal_code].matches(query)
where(name_match.or(postal_match)).page(page).per_page(5)
end
ActiveRecord 足够聪明,知道?
引用的参数是一个字符串,因此它将其括在单引号中。正如一篇文章建议的那样,您可以使用 Ruby 字符串插值来填充带有所需%
符号的字符串。但是,这可能会使您暴露于SQL注入(这很糟糕)。我建议您使用 SQL CONCAT()
函数来准备字符串,如下所示:
"name LIKE CONCAT('%',?,'%') OR postal_code LIKE CONCAT('%',?,'%')", search, search)
如果有人使用"key"
或"value"
等列名,那么您仍然会看到相同的错误,即您的mysql查询语法不正确。这应该可以解决:
.where("`key` LIKE ?", "%#{key}%")
尝试
def self.search(search, page = 1 )
paginate :per_page => 5, :page => page,
:conditions => ["name LIKE ? OR postal_code like ?", "%#{search}%","%#{search}%"], order => 'name'
end
有关详细信息,请参阅有关 AREL 条件的文档。
.find(:all, where: "value LIKE product_%", params: { limit: 20, page: 1 })