Undefined method 'each' for

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? :wink:

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

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. [email protected]:

voglio che la variabile @pupils contenga tutti gli alunni delle classi
@rclasses = @teach.rclasses


Ml mailing list
[email protected]
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: [email protected]
site: http://www.sistrall.it

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]

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

2009/6/10 Marco M. [email protected]:

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?

Msan M. wrote:

2009/6/10 Marco M. [email protected]:

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.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