2009-04-13 5 views
74

Parece que no puedo usar la opción ActiveRecord :: Base.find: ordene para más de una columna a la vez.Rails Active Record find (: all,: order =>) issue

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

Si funciono el siguiente código:

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

puedo obtener 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 funciono 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 me quedo :

@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") 

consigo los mismos resultados que sólo se puede clasificar 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 conseguir 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>] 
es la consulta que se generan

Esta 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 falta? ¿Qué estoy haciendo mal?

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

+0

no tengo una instalación de rieles en el momento de comprobar su código; ¿Qué consulta se genera para los dos comandos? Debería poder verificar los registros en/logs para ver. – YenTheFirst

+0

La consulta sería muy útil de hecho – aivarsak

+0

Quizás irrelevante, pero ¿qué versión de AR está usando y qué DB? –

Respuesta

36

noto que en su primer ejemplo, el simple : "fecha" orden =>, ficha se ordena antes de registro . 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 eran exactamente lo mismo, y la fecha de es anterior a la fecha de . En lugar de encontrar que fecha s son exactamente iguales que proceder a ordenar por atendiendo, la consulta encuentra que las fechas no son iguales y simplemente ordena por eso como todos los demás registros.

Veo al navegar que SQLite no tiene un conocimiento nativo de los tipos de datos DATE o DATETIME y en cambio le 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 la gente parece necesitar use date functions para que las fechas se comporten como cabría esperar. Tal vez haya una forma de envolver su pedido por columna con un date function que le dará algo concreto para comparar, como fecha (fecha) ASC, atendiendo a DESC. No estoy seguro de que la sintaxis funcione, pero es un área a mirar para resolver su problema. Espero que ayude.

+0

gracias. me has dado algo en qué pensar. – CodingWithoutComments

+0

Eso tiene sentido, la columna DATE podría ser un DATETIME o alguna otra parte fraccionaria, por lo que tendrías que pedir por fecha las partes ... Sí ... Good catch –

+4

Cambié las bases de datos de sqlite3 a mysql. Esto hizo que el problema desapareciera. – CodingWithoutComments

3

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

+0

sí, lo siento, gracias por señalar eso. Eso es lo que estaba haciendo. Corregido en cuestión. – CodingWithoutComments

+0

esto no funciona por alguna razón. Intenté esto. ¿Alguna otra idea? – CodingWithoutComments

3

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.

2

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 alegra que haya resuelto su problema.

+0

no podría estar más de acuerdo. Desarrolla con la misma base de datos en la que vas a implementar. Le ahorrará muchos dolores de cabeza a largo plazo. – brettish

2

Es bueno que haya encontrado su solución. Pero es un problema interesante. Lo probé 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 hagas si desea continuar la excavación en este problema es iniciar la aplicación sqlite3 de línea de comandos y comprobar el esquema y las consultas ahí:

Esto le muestra el esquema: .schema

Y a continuación, basta con ejecutar la instrucción de selección, ya que apareció en los archivos de registro: SELECT * FROM "shows" ORDER BY date ASC, attending DESC

Esa forma de ver si:

  1. El esquema se ve como lo desea (esa fecha es realmente 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 desordena el tipo)
14

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

ver esto: Sqlite3 activerecord :order => "time DESC" doesn't sort

44

Podría ser dos cosas.En primer lugar,

Este código está en desuso:

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

debería ser:

Model.order(...).all 

Find ya no es compatible con el: todos,: orden, y muchas otras opciones.

En segundo lugar, que podría haber tenido un default_scope que estaba haciendo cumplir algunos pedidos antes llamado find en Show.

horas de cavar alrededor en el Internet me llevaron a unos pocos artículos útiles que explican el problema:

+1

Model.all (: order => ...) está bien – mdpatrick

+0

'Model.order (...)' es mejor – Yule

+0

En rieles 4.1 Model.all (: order => "field_name ASC") da un número incorrecto de argumentos (1 de 0) error. El Model.order ("field_name ASC") no. Encontrado esto mientras actualiza una aplicación anterior. –

4

simplemente me encontré con el mismo problema, aunque me lograr que mi consulta funcione en SQLite de esta manera:

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

espero que esto podría ayudar a alguien a ahorrar algo de tiempo

0

Esto podría ayudar también:

Post.order(created_at: :desc) 
Cuestiones relacionadas