La respuesta de Mysql2 no funciona con el método de recopilación en Ruby

Estoy usando mysql2 en mi script Ruby. usando esto para probar las respuestas de la API contra mysql DB

este es un fragmento de mi script

test_job_by_id_5
 id = $data["jobs"]["id"][i] # example 5
 job = JobServices.job_by_id(id)
 response = @@con.query("select * from jobs where id = #{id}") #select * from jobs where id =5
 rs=response.collect #this fails
 assert_match(job[0]['title'],rs[0]['title'],"The title values are equal for #{$data["jobs"]["id"][i]}")
end

Así que cuando uso esto con ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-darwin10] funciona a las mil maravillas

pero cuando uso ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux] no funciona me sale este error

NoMethodError: undefined method '[]' for 
#<Enumerator: #<Mysql2::Result:0x00000012d19f18>:collect>

¿Puede alguien por favor ayudarme a arreglar esto?

preguntado el 01 de mayo de 12 a las 22:05

Primero consideraría usar comillas simples para sus cadenas de índice hash dentro del assert_match línea, solo para mayor claridad. -

Creo que estoy usando comillas simples, no estoy seguro de lo que quieres decir:

Tal vez mire la última cadena nuevamente, "Los valores del título ..." Ahora, ¿sabe a qué me refiero? -

o eso es porque quiero pasar una variable, puede ser que cambie todo a comillas dobles :) -

Estoy diciendo que use comillas simples para las claves hash para que sea más fácil de leer. No tengo que hacerlo, pero en mi opinión es más limpio. -

1 Respuestas

Cuando usted llama collect en un Enumerable (cual Mysql2::Result es), obtienes un Enumerator instancia de nuevo. Enumerators no implementa el operador de acceso a la matriz, por lo que no puede decir enumerator[0] y hacer que suceda algo útil; sin embargo, Enumerator incluye Enumerable por lo que responden a first así que probablemente quieras hacer esto:

rs  = response.collect
row = rs.first
assert_match(job[0]['title'], row['title'], "The title values are equal for #{$data["jobs"]["id"][i]}")

O simplemente sáltate el Enumerator por completo y llamar first al response:

row = response.first
assert_match(job[0]['title'], row['title'], "The title values are equal for #{$data["jobs"]["id"][i]}")

o incluso esto:

row = @@con.query("select * from jobs where id = #{id}").first
assert_match(job[0]['title'], row['title'], "The title values are equal for #{$data["jobs"]["id"][i]}")

Tenga en cuenta que row.nil? será verdadero si su consulta no encuentra nada, por lo que es posible que desee tenerlo en cuenta si no desea una excepción.

respondido 18 mar '19, 18:03

gracias por la respuesta, esto probablemente lo hará, pero necesito iterar sobre todas las filas devueltas, y no sé cuántas filas se devolverán. Utilizando each, pero en lugar de hacer each en la respuesta de la base de datos, necesito hacerlo para cada respuesta de la API. Así que no estoy seguro si hay un second y third - Amey

@perlnewbie: no estoy seguro de lo que quiere decir, pero tal vez pueda darle la vuelta o obtener todos los resultados en una matriz y luego iterar job y esa matriz al mismo tiempo. - mu es demasiado corto

quiero decir si lo hago response[0]['title'] sin usar collect no funciona. Entonces, básicamente, no puedo iterar el trabajo y la respuesta en el mismo ciclo si lo hago job.each do |i| assert_match(job[i]['title'],response[i]['title']) end - Amey

Pero puedes hacer response.each { ... } or response.each_with_index { ... } para iterar ambos a la vez. - mu es demasiado corto

Si proporciona el bloque para Enumerable#collect, obtiene una matriz del otro lado, esto puede ser costoso si el conjunto de resultados es grande, pero puede que no valga la pena preocuparse por un conjunto de pruebas. each_with_index podría ser una buena opción: response.each_with_index { |r, i| assert_match(job[i]['title'], r[i], ...) }. - mu es demasiado corto

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.