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