# Undefined method 'each' for

**URL:** <https://www.ruby-forum.com/t/undefined-method-each-for/169937>\
**Category:** IT\
**Created:** [June 10, 2009, 1:35pm UTC](https://www.ruby-forum.com/t/undefined-method-each-for/169937 "2009-06-10T13:35:43Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![triplem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b19c9b/32.png) [@triplem](https://www.ruby-forum.com/u/triplem)\
**Post date:** [June 10, 2009, 1:35pm UTC](https://www.ruby-forum.com/t/undefined-method-each-for/169937/1 "2009-06-10T13:35:43Z")

</div>

Salve a tutti,

sto lavorando al mio primo progetto Rails (implementazione di un  
registro di classe elettronico) e mi sto dannando da alcune ore su qs  
poche righe:

ho 3 model: Teacher, Rclass e Pupil,  
Teacher e Rclass sono legati da una relazione molti a molti,  
Pupil e Rclass sono legati da una relazione 1 a molti,

voglio che la variabile @pupils contenga tutti gli alunni delle classi  
associate ad un insegnante (@teach)

Mi dÃ :  
UNDEFINED METHOD ‘EACH’ FOR #Pupil:0x5e9dd24

Qualcuno mi dice dove sbaglio? 😉

Penso sia il FIND ma non so come altro esprimermi…

…  
@teach = Teacher.find(@current\_user.teacher\_id)  
@rclasses = @teach.rclasses  
@pupils = []  
for rclass in @rclasses  
@pups\_rclass = Pupil.find\_by\_rclass\_id(rclass.id)  
for pups\_rclass in @pups\_rclass  
@pupils \<\< pups\_rclass  
end  
end  
…

---

<div class="post-metadata">

**Author:** ![triplem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b19c9b/32.png) [@triplem](https://www.ruby-forum.com/u/triplem)\
**Post date:** [June 10, 2009, 2:16pm UTC](https://www.ruby-forum.com/t/undefined-method-each-for/169937/2 "2009-06-10T14:16:45Z")

</div>

Ciao,

il problema potrebbe stare in

@pups\_rclass = Pupil.find\_by\_rclass\_id(rclass.id)

Tu ti aspetti che restituisca un array di oggetti Pupils, mentre  
find\_by\_rclass\_id restituisce il primo record che soddisfa la  
condizione. Prova con:

@pups\_rclass = Pupil.find\_by\_all\_rclass\_id(rclass.id)

Ciao,  
Silvano

2009/6/10 Marco M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> voglio che la variabile @pupils contenga tutti gli alunni delle classi  
> @rclasses = @teach.rclasses
> 
> * * *
> 
> Ml mailing list  
> removed\_email\_address@domain.invalid  
> [http://lists.ruby-it.org/mailman/listinfo/ml](http://lists.ruby-it.org/mailman/listinfo/ml)

–  
Considera l’ambiente prima di stampare questa email. Dai, che  
l’equazione è semplice: meno A4, più alberi.

. . . Silvano S. . . .  
email: removed\_email\_address@domain.invalid  
site: [http://www.sistrall.it](http://www.sistrall.it)

---

<div class="post-metadata">

**Author:** ![triplem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b19c9b/32.png) [@triplem](https://www.ruby-forum.com/u/triplem)\
**Post date:** [June 10, 2009, 3:35pm UTC](https://www.ruby-forum.com/t/undefined-method-each-for/169937/3 "2009-06-10T15:35:36Z")

</div>

Ciao Marco,  
cerco di interpretarti il messaggio che ricevi, Ã¨ importante capire gli  
errori per non ripeterli: il metodo each non Ã¨ definito perchÃ¨ viene  
richiamato su un oggetto pupil mentre deve essere fatto su un array per  
scorrere gli elementi.

un alternativa al consiglio di Silvano Ã¨ una novitÃ di rails 2.3

@pups\_rclass = Pupil.scoped\_by\_rclass\_id(rclass.id)

find\_by effettua una find(:first) che restituisce un solo oggetto  
scoped\_by una find(:all) che restituisce un array di oggetti

inoltre se vuoi anche avere un occhio di riguardo sulle prestazioni  
potresti utilizzare direttamente una find, richiamare un metodo dinamico  
Ã¨ figo ma dispendioso

@pups\_rclass = Pupil.find :all, :conditions =\> [“rclass\_id = ?”,  
rclass.id]

---

<div class="post-metadata">

**Author:** ![triplem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b19c9b/32.png) [@triplem](https://www.ruby-forum.com/u/triplem)\
**Post date:** [June 10, 2009, 4:29pm UTC](https://www.ruby-forum.com/t/undefined-method-each-for/169937/4 "2009-06-10T16:29:25Z")

</div>

Silvano e Marco, GRAZIE MILLEEE!  
Da solo non ne sarei venuto fuori… funziona molto bene!  
Marco

---

<div class="post-metadata">

**Author:** ![triplem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b19c9b/32.png) [@triplem](https://www.ruby-forum.com/u/triplem)\
**Post date:** [June 11, 2009, 10:18am UTC](https://www.ruby-forum.com/t/undefined-method-each-for/169937/5 "2009-06-11T10:18:50Z")

</div>

2009/6/10 Marco M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Ciao Marco,  
> cerco di interpretarti il messaggio che ricevi, è importante capire gli  
> errori per non ripeterli: il metodo each non è definito perchè viene  
> richiamato su un oggetto pupil mentre deve essere fatto su un array per  
> scorrere gli elementi.
> 
> un alternativa al consiglio di Silvano è una novità di rails 2.3
> 
> @pups\_rclass = Pupil.scoped\_by\_rclass\_id(rclass.id)

La scoped\_by rispetto alla find\_by che fa di diverso?

---

<div class="post-metadata">

**Author:** ![triplem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b19c9b/32.png) [@triplem](https://www.ruby-forum.com/u/triplem)\
**Post date:** [June 12, 2009, 4:07pm UTC](https://www.ruby-forum.com/t/undefined-method-each-for/169937/6 "2009-06-12T16:07:52Z")

</div>

Msan M. wrote:

> 2009/6/10 Marco M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > Ciao Marco,  
> > cerco di interpretarti il messaggio che ricevi, ï¿½ importante capire gli  
> > errori per non ripeterli: il metodo each non ï¿½ definito perchï¿½ viene  
> > richiamato su un oggetto pupil mentre deve essere fatto su un array per  
> > scorrere gli elementi.
> > 
> > un alternativa al consiglio di Silvano ï¿½ una novitï¿½ di rails 2.3
> > 
> > @pups\_rclass = Pupil.scoped\_by\_rclass\_id(rclass.id)
> 
> La scoped\_by rispetto alla find\_by che fa di diverso?

La spiegazione migliore tutto sommato mi sembra il manuale di  
ActiveRecord::NamedScope::ClassMethods nel sito ufficiale dell’API di  
Rails

[http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html](http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html)  
[http://api.rubyonrails.org/classes/ActiveRecord/NamedScope.html](http://api.rubyonrails.org/classes/ActiveRecord/NamedScope.html)

Riporto un piccolo estratto del primo, ma nel doc ci sono tante altre  
cose interessanti:

* * *

class Shirt \< ActiveRecord::Base  
named\_scope :red, :conditions =\> {:color =\> ‘red’}  
named\_scope :dry\_clean\_only, :joins =\> :washing\_instructions,  
:conditions =\> [‘washing\_instructions.dry\_clean\_only = ?’, true]  
end

The above calls to named\_scope define class methods Shirt.red and  
Shirt.dry\_clean\_only. Shirt.red, in effect, represents the query  
Shirt.find(:all, :conditions =\> {:color =\> â€˜redâ€™}).

## Unlike Shirt.find(…), however, the object returned by Shirt.red is not an Array; it resembles the association object constructed by a has\_many declaration. For instance, you can invoke Shirt.red.find(:first), Shirt.red.count, Shirt.red.find(:all, :conditions =\> {:size =\> â€˜smallâ€™}).

Utile per crearsi i propri metodi risparmiando caratteri, conditions e  
bug dovuti a copiature e mancati aggiornamenti. Rende Rails piÃ¹ DRY.

scoped\_by Ã¨ un metodo dinamico che crea gli scope al volo. La  
documentazione non Ã¨ granchÃ©. Ne ho trovata dentro a  
lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active\_record/base.rb,  
davanti al metodo method\_missing che intercetta tutte le chiamate a  
metodi non definiti (Ã¨ il meccanismo con cui funzionano i find\_by).  
Riporto:

* * *

[method\_missing] Enables dynamic finders like  
find\_by\_user\_name(user\_name) and  
find\_by\_user\_name\_and\_password(user\_name, password)  
that are turned into find(:first, :conditions =\> [“user\_name = ?”,  
user\_name]) and find(:first, :conditions =\> [“user\_name = ? AND password  
= ?”, user\_name, password]) respectively.  
Also works for find(:all) by using find\_all\_by\_amount(50) that is turned  
into find(:all, :conditions =\> [“amount = ?”, 50]).

It’s even possible to use all the additional parameters to +find+. For  
example, the full interface for +find\_all\_by\_amount+ is actually  
find\_all\_by\_amount(amount, options)-

Also enables dynamic scopes like scoped\_by\_user\_name(user\_name) and  
scoped\_by\_user\_name\_and\_password(user\_name, password) that  
are turned into scoped(:conditions =\> [“user\_name = ?”, user\_name]) and  
scoped(:conditions =\> [“user\_name = ? AND password = ?”, user\_name,  
password]) respectively.

## Each dynamic finder, scope or initializer/creator is also defined in the class after it is first invoked, so that future

Paolo
