ActiveRecord trouve et renvoie uniquement les colonnes sélectionnées

88

modifier 2

Si vous tombez sur ceci, vérifiez les deux réponses car j'utiliserais maintenant pluck pour cela


J'ai un ensemble de données personnalisé assez volumineux que j'aimerais retourner pour être repris en tant que json. Une partie est:

l=Location.find(row.id)
tmp[row.id]=l

mais j'aimerais faire quelque chose comme:

l=Location.find(row.id).select("name, website, city")
tmp[row.id]=l

mais cela ne semble pas fonctionner. Comment pourrais-je faire fonctionner cela?

THX

edit 1
alternativement, existe-t-il un moyen de transmettre un tableau contenant uniquement les attributs que je veux inclure?

timpone
la source

Réponses:

85

Dans les rails 2

l = Location.find(:id => id, :select => "name, website, city", :limit => 1)

...ou...

l = Location.find_by_sql(:conditions => ["SELECT name, website, city FROM locations WHERE id = ? LIMIT 1", id])

Ce document de référence vous donne la liste complète des options que vous pouvez utiliser avec .find, y compris comment limiter par nombre, id ou toute autre colonne / contrainte arbitraire.

In Rails 3 avec interface de requête ActiveRecord

l = Location.where(["id = ?", id]).select("name, website, city").first

Réf: Interface de requête d'enregistrement actif

Vous pouvez également permuter l'ordre de ces appels chaînés, en faisant .select(...).where(...).first- tous ces appels font est de construire la requête SQL, puis de l'envoyer.

Jefflunt
la source
mais je ne veux qu'une seule instance pas tout
timpone
J'ai édité ma réponse. :limitdevrait faire ceci, ou :firstou :lastou quoi que ce soit, selon ce que vous voulez. Le document de référence auquel j'ai lié vous dira comment faire tout cela.
jefflunt
Mise à jour pour inclure comment faire une requête équivalente dans Rails 3.
jefflunt
205

pluck (nom_colonne)

Cette méthode est conçue pour effectuer une sélection par une seule colonne en tant que requête SQL directe Renvoie Tableau avec les valeurs du nom de colonne spécifié Les valeurs ont le même type de données que la colonne.

Exemples:

Person.pluck(:id) # SELECT people.id FROM people
Person.uniq.pluck(:role) # SELECT DISTINCT role FROM people
Person.where(:confirmed => true).limit(5).pluck(:id)

voir http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-pluck

Ses rails introduits à partir de 3.2 et n'acceptent qu'une seule colonne. Dans les rails 4, il accepte plusieurs colonnes

prasad.surase
la source
1
OK, plumer avec plusieurs colonnes est génial .. je viens d'apprendre cela sur cette réponse. Les rails 3 ont cependant besoin de la réponse acceptée.
Jay Shepherd
La réponse acceptée est juste car le pluck n'était pas disponible à l'époque.
prasad.surase
User.pluck (: email,: id) SELECT "users". "Email", "users". "Id" FROM "users"
pranav prashant
2
Model.uniq est maintenant Model.distinct (au moins dans Rails 5).
mrturtle
Il semble que vous pouvez faire ce qui suit dans les rails 3.2: Location.select([:name, :website, :city])si vous lui passez un tableau
CTS_AE
22

Ma réponse arrive assez tard car je suis un développeur assez récent. Voici ce que vous pouvez faire:

Location.select(:name, :website, :city).find(row.id)

Btw, c'est Rails 4

tkhuynh
la source
Cela devrait être la réponse choisie et répond le plus directement à la question.
Michael Wiltbank