ruby-on-rails - crear - rails api tutorial
Consulta de Rails 4 Ășnica por atributo Ășnico (6)
Así que esto es más una pregunta que cualquier otra cosa, pero esto es lo que estoy tratando de hacer.
Tengo tres objetos, digamos artículos
<Item id: 1, name: ''Book''>
<Item id: 2, name: ''Car''>
<Item id: 3, name: ''Book''>
Quiero hacer una consulta que solo devolverá uno de cada atributo de "nombre" único.
Algo como Item.select(''distinct(name), items.*'')
Esto no funciona, sin embargo, todavía devuelve los tres elementos.
¿Cómo puedo formar esta consulta para que solo devuelva:
<Item id: 1, name: ''Book''>
<Item id: 2, name: ''Car''>
En Rails 4 intente Items.all.to_a.uniq { |item| item.name }
Items.all.to_a.uniq { |item| item.name }
En Rails 3 deberías poder hacer Items.uniq_by { |item| item.name }
Items.uniq_by { |item| item.name }
Cuando llama a uniq
en una matriz, puede pasarle un bloque para dictar cómo determinar la singularidad. En Rails 3 uniq_by
poder usar uniq_by
, pero se desaprobó en Rails 4. Así que un método que encontré es simplemente convertir la relación ActiveRecord a una matriz y llamar a uniq
en eso.
La siguiente es una consulta ORM de Rails que producirá el resultado deseado con todas las versiones más recientes de Rails rails 5.X.
@unique_values= []
Model.all.group_by(&:column_name).each do |key, val|
if val.count == 1
@unique_values << val
else
@unique_values << val.first
end
end
Para Mysql, puedes usar el group
con ONLY_FULL_GROUP_BY deshabilitado,
Item.group(:name).to_sql
=> "SELECT `items`.* FROM `items` GROUP BY name"
Por favor intente esto:
Item.select(''distinct name'')
Si desea recuperar todo el modelo, pero aún así mantener la singularidad, puede usar esto:
Item.select(''distinct on (name) *'')
Sólo he probado esto con una base de datos Postgres. Puede o no puede funcionar con mysql.
Si solo necesita una matriz con los nombres, sin el ID, puede hacer:
Item.pluck(:name).uniq
Resultado de la consulta SQL:
#=> SELECT `items`.`name` FROM `items`
** editar **
El uniq
se ejecuta en la matriz de registros. Ten cuidado si esperas muchos discos. SQL Distinct es mucho más rápido.
Si es así, usa la respuesta de vee arriba, con un map
:
Item.select(''distinct name'').map(:name)