started software rubyonrails rails getting generators and ruby-on-rails ruby activerecord

ruby-on-rails - software - rubyonrails



Rails Active Record find(: all,: order=>) problema (9)

¿no es solo :order => ''column1 ASC, column2 DESC'' ?

Parece que no puedo usar la opción ActiveRecord :: Base.find: orden para más de una columna a la vez.

Por ejemplo, tengo un modelo "Mostrar" con fecha y columnas asistentes.

Si ejecuto el siguiente código:

@shows = Show.find(:all, :order => "date")

Obtengo los siguientes resultados:

[#<Show id: 7, date: "2009-04-18", attending: 2>, #<Show id: 1, date: "2009-04-18", attending: 78>, #<Show id: 2, date: "2009-04-19", attending: 91>, #<Show id: 3, date: "2009-04-20", attending: 16>, #<Show id: 4, date: "2009-04-21", attending: 136>]

Si ejecuto el siguiente código:

@shows = Show.find(:all, :order => "attending DESC") [#<Show id: 4, date: "2009-04-21", attending: 136>, #<Show id: 2, date: "2009-04-19", attending: 91>, #<Show id: 1, date: "2009-04-18", attending: 78>, #<Show id: 3, date: "2009-04-20", attending: 16>, #<Show id: 7, date: "2009-04-18", attending: 2>]

Pero, si corro:

@shows = Show.find(:all, :order => "date, attending DESC")

O

@shows = Show.find(:all, :order => "date, attending ASC")

O

@shows = Show.find(:all, :order => "date ASC, attending DESC")

Obtengo los mismos resultados que solo clasificando por fecha:

[#<Show id: 7, date: "2009-04-18", attending: 2>, #<Show id: 1, date: "2009-04-18", attending: 78>, #<Show id: 2, date: "2009-04-19", attending: 91>, #<Show id: 3, date: "2009-04-20", attending: 16>, #<Show id: 4, date: "2009-04-21", attending: 136>]

Donde como, quiero obtener estos resultados:

[#<Show id: 1, date: "2009-04-18", attending: 78>, #<Show id: 7, date: "2009-04-18", attending: 2>, #<Show id: 2, date: "2009-04-19", attending: 91>, #<Show id: 3, date: "2009-04-20", attending: 16>, #<Show id: 4, date: "2009-04-21", attending: 136>]

Esta es la consulta que se genera a partir de los registros:

[4;35;1mUser Load (0.6ms)[0m [0mSELECT * FROM "users" WHERE ("users"."id" = 1) LIMIT 1[0m [4;36;1mShow Load (3.0ms)[0m [0;1mSELECT * FROM "shows" ORDER BY date ASC, attending DESC[0m [4;35;1mUser Load (0.6ms)[0m [0mSELECT * FROM "users" WHERE ("users"."id" = 1) [0m

Finalmente, aquí está mi modelo:

create_table "shows", :force => true do |t| t.string "headliner" t.string "openers" t.string "venue" t.date "date" t.text "description" t.datetime "created_at" t.datetime "updated_at" t.decimal "price" t.time "showtime" t.integer "attending", :default => 0 t.string "time" end

¿Qué me estoy perdiendo? ¿Qué estoy haciendo mal?

ACTUALIZACIÓN: Gracias por toda su ayuda, pero parece que todos ustedes estaban perplejos tanto como yo. Lo que resolvió el problema fue cambiar las bases de datos. Cambié del sqlite3 predeterminado a mysql.


Asegúrese de verificar el esquema en el nivel de la base de datos directamente. Me he quemado con esto antes, donde, por ejemplo, una migración se escribió inicialmente para crear una columna: datetime, y la ejecuté localmente, luego ajusté la migración a una fecha anterior a la implementación. Por lo tanto, la base de datos de todos se ve bien, excepto la mía, y los errores son sutiles.


El problema es que la fecha es una palabra clave sqlite3 reservada . Tuve un problema similar con el tiempo , también una palabra clave reservada, que funcionó bien en PostgreSQL, pero no en sqlite3. La solución es cambiar el nombre de la columna .

Ver esto: Sqlite3 activerecord: order => "time DESC" no ordena


Entiendo por qué los desarrolladores de Rails fueron con sqlite3 para una implementación lista para usar, pero MySQL es mucho más práctico, en mi humilde opinión. Me doy cuenta de que depende de para qué estás construyendo tu aplicación Rails, pero la mayoría de las personas cambiarán el archivo predeterminado database.yml de sqlite3 a MySQL.

Me alegro de que resolvió su problema.


Es bueno que hayas encontrado tu solución. Pero es un problema interesante. Lo intenté directamente con sqlite3 (no pasando por los rieles) y no obtuve el mismo resultado, para mí el pedido salió como se esperaba.

Lo que sugiero que haga si desea continuar investigando este problema es iniciar la aplicación de línea de comandos sqlite3 y verificar el esquema y las consultas allí:

Esto te muestra el esquema: .schema

Y luego simplemente ejecute la instrucción Select tal como aparece en los archivos de registro: SELECT * FROM "shows" ORDER BY date ASC, attending DESC

De esa forma, verás si:

  1. El esquema se ve como lo desea (esa fecha es en realidad una fecha, por ejemplo)
  2. Que la columna de fecha realmente contiene una fecha y no una marca de tiempo (es decir, que no tiene una hora del día que estropee el orden)

Esto también podría ayudar:

Post.order(created_at: :desc)


Me encontré con el mismo problema, pero logro que mi consulta funcione en SQLite de esta manera:

@shows = Show.order("datetime(date) ASC, attending DESC")

Espero que esto pueda ayudar a alguien a ahorrar algo de tiempo


Noté que en su primer ejemplo, simple : order => "date" , el registro 7 está ordenado antes del registro 1 . Este orden también es la forma de ver los resultados en el orden de varias columnas, independientemente de si ordena por asistir.

Esto parece tener sentido para mí si las fechas no son exactamente las mismas, y la fecha para 7 es anterior a la fecha para 1 . En lugar de encontrar que la fecha s es exactamente igual que proceder a ordenar atendiendo , la consulta encuentra que las fechas no son iguales y simplemente ordena por eso como todos los demás registros.

Al navegar, observé que SQLite no tiene un conocimiento nativo de los tipos de datos DATE o DATETIME y, en su lugar, les da a los usuarios la opción de números de coma flotante o texto que deben analizarse ellos mismos. ¿Es posible que la representación literal de las fechas en la base de datos no sea exactamente igual? La mayoría de las personas parece necesitar usar funciones de fecha para que las fechas se comporten como es de esperar. Tal vez haya una manera de ajustar su orden por columna con una función de fecha que le dará algo concreto para comparar, como la fecha (fecha) ASC, que asiste a DESC . No estoy seguro de que la sintaxis funcione, pero es un área a mirar para resolver su problema. Espero que ayude.


Podrían ser dos cosas Primero,

Este código está en desuso

Model.find(:all, :order => ...)

debiera ser:

Model.order(...).all

Buscar ya no es compatible con: todo,: orden y muchas otras opciones.

En segundo lugar, es posible que haya tenido un default_scope que impuso algún pedido antes de llamar a find en Show .

Las horas de búsqueda en Internet me llevaron a algunos artículos útiles que explican el problema: