Consulta similar A Rails 4-ActiveRecord añade comillas


Estoy tratando de hacer una consulta como así

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

Pero cuando se ejecuta algo es agregar comillas lo que hace que la instrucción sql salga así

SELECT COUNT(*)
FROM "schools" 
WHERE (name LIKE '%'havard'%' OR postal_code like '%'havard'%')):

Así que puedes ver mi problema. Estoy usando Rails 4 y Postgres 9, los cuales nunca he usado, así que no estoy seguro de si es una cosa de activerecord o posiblemente una cosa de postgres.

¿Cómo puedo configurar esto para que tenga como '%my_search%' en la consulta final?

Author: hforbess, 2013-10-01

6 answers

Su marcador de posición se reemplaza por una cadena y no lo está manejando correctamente.

Sustitúyase

"name LIKE '%?%' OR postal_code LIKE '%?%'", search, search

Con

"name LIKE ? OR postal_code LIKE ?", "%#{search}%", "%#{search}%"
 190
Author: rb512,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-10 19:48:21

En lugar de usar la sintaxis conditions de Rails 2, use el método where de Rails 4 en su lugar:

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

NOTA: lo anterior usa sintaxis de parámetros en lugar de ? marcador de posición: ambos deben generar el mismo 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

NOTA: usando ILIKE para el nombre - postgres versión insensible a mayúsculas y minúsculas de LIKE

 46
Author: house9,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-13 23:08:29

Mientras que la interpolación de cadenas funcionará, como su pregunta especifica rails 4, podría usar Arel para esto y mantener su base de datos de aplicaciones agnóstica.

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
 21
Author: numbers1311407,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-30 00:29:23

Intenta

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

Consulte los documentos sobre las condiciones de AREL para obtener más información.

 5
Author: tihom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-30 23:57:49

ActiveRecord es lo suficientemente inteligente como para saber que el parámetro al que se refiere ? es una cadena, por lo que lo encierra entre comillas simples. Usted podría como un post sugiere usar interpolación de cadena Ruby para rellenar la cadena con los símbolos % requeridos. Sin embargo, esto podría exponerlo a SQL-injection (que es malo). Te sugiero que uses la función SQL CONCAT() para preparar la cadena así:

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

 5
Author: John Cleary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-28 12:50:27
.find(:all, where: "value LIKE product_%", params: { limit: 20, page: 1 })
 -1
Author: Jeff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-28 08:14:07