sql - queries - rails console activerecord
Rails 4 LIKE query-ActiveRecord agrega comillas (6)
ActiveRecord es lo suficientemente inteligente como para saber que el parámetro al que hace referencia el ?
es una cadena, por lo que la encierra en comillas simples. Podrías , como una publicación, sugerir el uso de la interpolación de cadenas de Ruby para rellenar la cadena con los símbolos %
requeridos. Sin embargo, esto podría exponerte a una inyección SQL (que es mala). Sugeriría que use la función SQL CONCAT()
para preparar la cadena de esta manera:
"name LIKE CONCAT(''%'',?,''%'') OR postal_code LIKE CONCAT(''%'',?,''%'')", search, search)
Estoy tratando de hacer una consulta similar como tal
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, se agregan comillas, lo que hace que la sentencia sql salga como
SELECT COUNT(*)
FROM "schools"
WHERE (name LIKE ''%''havard''%'' OR postal_code like ''%''havard''%'')):
Entonces puedes ver mi problema. Estoy usando Rails 4 y Postgres 9, ambos de los cuales nunca he usado, así que no estoy seguro de si es algo de activerecord o posiblemente algo de postgres.
¿Cómo puedo configurar esto para que tenga como ''%my_search%''
en la consulta final?
En lugar de usar la sintaxis de conditions
de Rails 2, use Rails 4''s where
method 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ámetro en lugar de? marcador de posición: ambos deberían 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: utilizando ILIKE
para el nombre - postgres insensible a mayúsculas / minúsculas, versión de LIKE
Si bien la interpolación de cadenas funcionará, ya que su pregunta especifica los rieles 4, podría estar usando Arel para esto y mantener la base de datos de su aplicación independiente.
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
Tratar
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 docs en condiciones AREL para obtener más información.
Tu marcador de posición se reemplaza por una cadena y no lo estás manejando bien.
Reemplazar
"name LIKE ''%?%'' OR postal_code LIKE ''%?%''", search, search
con
"name LIKE ? OR postal_code LIKE ?", "%#{search}%", "%#{search}%"
.find(:all, where: "value LIKE product_%", params: { limit: 20, page: 1 })