2009-06-10 4 views
5

Cette question est assez simple mais j'ai rencontré le problème plusieurs fois.Comment effectuer une itération sur des objets d'enregistrement actifs dans Ruby On Rails?

Disons que vous faites quelque chose comme:

cars = Vehicle.find_by_num_wheels(4) 

cars.each do |c| 
    puts "#{c.inspect}" 
end 

Cela fonctionne très bien si les voitures est un tableau, mais échoue s'il n'y a qu'une seule voiture dans la base de données. Évidemment, je pourrais faire quelque chose comme "if! Cars.length.nil?" ou vérifiez d'une autre manière si l'objet cars est un tableau avant d'appeler .each, mais c'est un peu ennuyeux à faire à chaque fois.

Y at-il quelque chose de similaire à .Chaque qui gère cette vérification pour vous? Ou existe-t-il un moyen facile de forcer le résultat de la requête dans un tableau indépendamment de la taille?

Répondre

12

Vous cherchez peut-être

cars = Vehicle.find_all_by_num_wheels(4) 

Les méthodes dynamiques find_by_ ne renvoient qu'un seul élément et vous devez utiliser find_all_by_ pour revenir multiples.

2

Si vous voulez toujours toutes les voitures, vous devez utiliser find_all à la place:

cars = Vehicle.find_all_by_num_wheels(4) 

Vous pouvez également activer un seul Vehicle dans un tableau avec:

cars = [cars] unless cars.respond_to?(:each) 
0

Vous pouvez le faire à obtenir everytimes de tableaux:

cars = Vehicle.find(:all, :conditions => {num_wheels => 4}) 

Je ne pense pas que vous avez une boucle qui va vérifier si l'objet est un tableau.

Une autre solution pourrait être:

for i in (1..cars.lenght) 
    puts cars[i].inspect 
end 

(ont pas testé, il pourrait se casser pour tester la longueur sur une chaîne Laissez-moi savoir si elle le fait.)

2

nommé la version scope pour votre problème

Vehicle.scoped(:conditions => { :num_wheels => 4 }).each { |car| car.inspect } 
+0

Je pense que ce serait une portée anonyme, vu comment vous ne l'avez pas nommé. Les portées sont une bonne réponse à cela, cependant. – Chuck