Estoy tratando de encontrar a todos los usuarios con una identificación superior a 200, pero tengo algunos problemas con la sintaxis específica.
User.where(:id > 200)
y
User.where("? > 200", :id)
Ambos han fallado.
¿Alguna sugerencia?
ruby-on-rails
syntax
where
Adam Templeton
fuente
fuente
?
, en lugar de incluir el200
?Solo he probado esto en Rails 4, pero hay una forma interesante de usar un rango con un
where
hash para obtener este comportamiento.generará el SQL
Lo mismo se puede hacer por menos que con
-Float::INFINITY
.Acabo de publicar una pregunta similar sobre cómo hacer esto con fechas aquí en SO .
>=
vs>
Para evitar que las personas tengan que profundizar y seguir la conversación de comentarios, aquí están los aspectos más destacados.
El método anterior solo genera una
>=
consulta y no a>
. Hay muchas formas de manejar esta alternativa.Para números discretos
Puede utilizar una
number_you_want + 1
estrategia como la anterior en la que estoy interesado en Usuarios con los queid > 200
realmente buscoid >= 201
. Esto está bien para números enteros y números donde puede incrementar en una sola unidad de interés.Si tiene el número extraído en una constante bien nombrada, este puede ser el más fácil de leer y comprender de un vistazo.
Lógica invertida
Podemos usar el hecho de que
x > y == !(x <= y)
y usar la cadena where not.que genera el SQL
Esto toma un segundo extra para leer y razonar, pero funcionará para valores no discretos o columnas donde no puede usar el
+ 1
estrategia.Mesa Arel
Si quieres ponerte elegante, puedes usar el
Arel::Table
.generará el SQL
Los detalles son los siguientes:
Este enfoque le dará el SQL exacto que le interesa, sin embargo, no muchas personas usan la tabla Arel directamente y pueden encontrarla desordenada y / o confusa. Usted y su equipo sabrán qué es lo mejor para usted.
Prima
¡A partir de Rails 5 también puedes hacerlo con las fechas!
generará el SQL
Doble bonificación
Una vez que se lance Ruby 2.6 (25 de diciembre de 2018), ¡podrá usar la nueva sintaxis de rango infinito! En lugar de
201..Float::INFINITY
solo podrás escribir201..
. Más información en esta publicación de blog .fuente
where
comparadores básicos . Pues>
sugiero usar un>= (number_you_want + 1)
para simplificar. Si realmente quiere asegurarse de que es solo una>
consulta, puede acceder a la tabla ARel. Cada clase que heredaActiveRecord
tiene unarel_table
método getter que devuelve elArel::Table
para esa clase. Se accede a las columnas de la tabla con el[]
método likeUser.arel_table[:id]
. Esto devuelve unArel::Attributes::Attribute
que puede llamargt
y pasar200
. Esto se puede pasar awhere
. por ejUser.where(User.arel_table[:id].gt(200))
.User.where(created_at: 3.days.ago..DateTime::Infinity.new)
.WHERE (users.created_at >= '2016-04-09 14:31:15' AND users.created_at < #<Date::Infinity:0x00>)
(se omiten los ticks posteriores alrededor de los nombres de tabla y columna para el formato de comentario SO).Un mejor uso es crear un alcance en el modelo de usuario
where(arel_table[:id].gt(id))
fuente
Si desea una escritura más intuitiva, existe una gema llamada Squeel que le permitirá escribir sus instrucciones de esta manera:
Observe que los caracteres de 'llave' {}
id
son solo un texto.Todo lo que tienes que hacer es agregar chirrido a tu Gemfile:
Esto podría facilitarle la vida al escribir sentencias SQL complejas en Ruby.
fuente
Arel es tu amiga.
fuente
Otra posibilidad elegante es ...
Esta característica le permite crear consultas más comprensibles si desea reemplazar en varios lugares, por ejemplo ...
Esto tiene más significado que tener mucho
?
en la consulta ...fuente
A menudo tengo este problema con los campos de fecha (donde los operadores de comparación son muy comunes).
Para dar más detalles sobre la respuesta de Mihai, que creo que es un enfoque sólido.
A los modelos puede agregar ámbitos como este:
... y luego en su controlador, o donde sea que esté usando su modelo:
... un ejemplo más complejo con combinaciones se ve así:
Una gran ventaja de este enfoque es que (a) le permite componer sus consultas desde diferentes ámbitos y (b) evita las colisiones de alias cuando se une a la misma tabla dos veces, ya que arel_table manejará esa parte de la generación de consultas.
fuente
Carriles 6.1+
Rails 6.1 agregó una nueva 'sintaxis' para operadores de comparación en
where
condiciones, por ejemplo:Entonces su consulta puede reescribirse de la siguiente manera:
Aquí hay un enlace a relaciones públicas donde puede encontrar más ejemplos.
fuente
Corta:
fuente
where("id > ?", 200)
sintaxis). Esto no logra eso.