Rails 4 LIKE 查询 - ActiveRecord 添加引号



我正在尝试做这样的类似查询

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}%"
不要使用 Rails

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 })

最新更新