Rails 4 LIKE查询 - ActiveRecord添加引号

Har*_*ess 120 ruby sql postgresql activerecord ruby-on-rails

我想尝试做类似的查询

def self.search(search, page = 1 )
  paginate :per_page => 5, :page => page,
    :conditions => ["name LIKE '%?%' OR postal_code like '%?%'", search, search],   order => 'name'
end
Run Code Online (Sandbox Code Playgroud)

但是当它运行时,有些东西正在添加引号,这会导致sql语句如此出现

SELECT COUNT(*)
FROM "schools" 
WHERE (name LIKE '%'havard'%' OR postal_code like '%'havard'%')):
Run Code Online (Sandbox Code Playgroud)

所以你可以看到我的问题.我正在使用Rails 4和Postgres 9这两个我从未使用过的,所以不确定它是否是一个活跃的记录或者可能是一个postgres的东西.

我该如何设置它以便我'%my_search%'最终在查询中喜欢?

rb5*_*512 216

您的占位符由字符串替换,您没有正确处理它.

更换

"name LIKE '%?%' OR postal_code LIKE '%?%'", search, search
Run Code Online (Sandbox Code Playgroud)

"name LIKE ? OR postal_code LIKE ?", "%#{search}%", "%#{search}%"
Run Code Online (Sandbox Code Playgroud)

  • 在这种方法下,@ search9里面的`%`和`_`实例将不会被清理. (7认同)
  • @ jdscosta91```在哪里会照顾消毒 (6认同)
  • 使用'?'时 以这种方式在rails中它被转换为参数化查询.参数中的数据未经过清理(%),但无法更改查询中的上下文并将其转换为已处理的SQL语句. (6认同)
  • 这不易受SQL注入攻击吗?我的意思是,这些"搜索"字符串是否已经过消毒? (5认同)

hou*_*se9 50

而不是使用conditionsRails 2中的语法,而是使用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
Run Code Online (Sandbox Code Playgroud)

注意:上面使用参数语法而不是?占位符:这两者都应该生成相同的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
Run Code Online (Sandbox Code Playgroud)

注意:使用ILIKE名称 - postgres不区分大小写的LIKE


num*_*407 21

虽然字符串插值可以正常工作,因为您的问题指定了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
Run Code Online (Sandbox Code Playgroud)


Joh*_*ary 7

ActiveRecord非常聪明,知道该引用的参数?是一个字符串,因此它将它用单引号括起来.你可以像一篇文章建议使用Ruby字符串插值来填充所需%符号的字符串.但是,这可能会使您暴露于SQL注入(这很糟糕).我建议你使用SQL CONCAT()函数来准备字符串,如下所示:

"name LIKE CONCAT('%',?,'%') OR postal_code LIKE CONCAT('%',?,'%')", search, search)


man*_*sim 7

如果有人使用像"key"或 这样的列名"value",那么您仍然会看到相同的错误,表明您的 mysql 查询语法不好。这应该修复:

.where("`key` LIKE ?", "%#{key}%")
Run Code Online (Sandbox Code Playgroud)


tih*_*hom 5

尝试

 def self.search(search, page = 1 )
    paginate :per_page => 5, :page => page,
      :conditions => ["name LIKE  ? OR postal_code like ?", "%#{search}%","%#{search}%"],   order => 'name'
  end
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅AREL条件的文档.