Mejores prácticas para obtener una lista de ID de un modelo ActiveRecord

Tengo un Language modelo de ActiveRecord, con las columnas id y short_code (hay otras columnas, pero no son relevantes para esta pregunta). Quiero crear un método al que se le dará una lista de códigos cortos y devolver una lista de ID. No me importan las asociaciones, solo necesito terminar con una matriz que se parece a [1, 2, 3, …].

Mi primer pensamiento fue hacer algo como

 def get_ids_from_short_codes(*short_codes) Language.find_all_by_short_code(short_codes.flatten, :select => 'id').map(&:id) end 

pero no estoy seguro si eso es innecesariamente perder tiempo / memoria / procesamiento.

Mi pregunta es doble:

  1. ¿Hay una manera de ejecutar un hallazgo de ActiveRecord que simplemente devuelva una matriz de una determinada columna de tabla en lugar de crear una instancia de objetos?
  2. Si es así, ¿realmente valdría la pena recostackr una matriz de longitud n en lugar de crear una instancia de n objetos ActiveRecord?

Tenga en cuenta que para mi propósito específico, n sería aproximadamente 200.

Sinceramente, para 200 discos, no me preocuparía por eso. Cuando llegue a 2000, 20,000 o 200,000 registros, entonces puede preocuparse por la optimización.

Asegúrate de que tienes un short_code indexado en tu tabla.

Si aún está preocupado por el rendimiento, eche un vistazo a development.log y vea cuáles son los números de la base de datos para esa llamada en particular. Puede ajustar la consulta y ver cómo afecta el rendimiento en el registro. Esto debería darle una estimación aproximada del rendimiento.

En Rails 3.x, puede usar el método pluck que devuelve los valores del campo solicitado sin crear una instancia de los objetos para mantenerlos.

Esto le daría una serie de ID:

 Language.where(short_code: short_codes.flatten).pluck(:id) 

Debería mencionar que en Rails 3.x puede arrancar solo una columna a la vez, pero en Rails 4 puede pasar varias columnas para arrancar.

Por cierto, aquí hay una respuesta similar a una pregunta similar

De acuerdo con la respuesta anterior, pero si es absolutamente necesario, puede intentar esto

 sql = Language.send(:construct_finder_sql, :select => 'id', :conditions => ["short_code in (?)", short_codes]) Language.connection.select_values(sql) 

Un poco feo, pero no crea objetos en la memoria.

Si está utilizando asociaciones, puede obtener identificadores sin procesar directamente desde ActiveRecord. p.ej.:

 class User < ActiveRecord::Base has_many :users end irb:=> User.find(:first).user_ids irb:>> [1,2,3,4,5] 

Phil tiene razón en esto, pero si encuentras que esto es un problema. Puede enviar una consulta de SQL sin formato a la base de datos y trabajar a un nivel por debajo de ActiveRecord. Esto puede ser útil para situaciones como esta.

 ActiveRecord::Base.connection.execute("SQL CODE!") 

Evalúa tu código primero antes de recurrir a esto.

Esto realmente es una cuestión de elección.

Overkill o no, ActiveRecord se supone que te da objetos ya que es un ORM. Y como dijo Ben, si no quieres objetos, usa SQL en bruto.