# \[rails\] come mai la mia classe risponde al metodo "valid?"

**URL:** <https://www.ruby-forum.com/t/rails-come-mai-la-mia-classe-risponde-al-metodo-valid/114211>\
**Category:** IT\
**Created:** [September 10, 2007, 12:16am UTC](https://www.ruby-forum.com/t/rails-come-mai-la-mia-classe-risponde-al-metodo-valid/114211 "2007-09-10T00:16:18Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gian\_marco\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/f475e1/32.png) [@Gian\_marco\_G](https://www.ruby-forum.com/u/Gian_marco_G)\
**Post date:** [September 10, 2007, 12:16am UTC](https://www.ruby-forum.com/t/rails-come-mai-la-mia-classe-risponde-al-metodo-valid/114211/1 "2007-09-10T00:16:18Z")

</div>

Ciao a tutti  
Sono nuovo del mondo Ruby/Rails.  
Ho definito una classe nel modo seguente

class Expense \< ActiveRecord::Base  
end

ed un semplice test

class ExpenseTest \< Test::Unit::TestCase  
def test\_required\_fields  
expense = Expense.new  
assert expense.valid?  
end  
end

Il test passa ma non riesco a capire dove Ã¨ definito il metodo “valid?”

Le mie considerazioni sono concentrate in questo metodo di test

def test\_find\_method\_valid  
expense = Expense.new  
assert expense.respond\_to?(“valid?”) # =\> true  
assert !Expense.respond\_to?(“valid?”) # =\> false  
assert expense.is\_a?(ActiveRecord::Base) # =\> true  
assert !ActiveRecord::Base.respond\_to?(“valid?”) # =\> false  
assert expense.is\_a?(ActiveRecord::Validations) # =\> true  
assert !ActiveRecord::Base.is\_a?(ActiveRecord::Validations) # =\>  
false  
assert !ActiveRecord::Validations.respond\_to?(“valid?”) # =\> false

```
assert expense.methods.include?("valid?") # => true
assert !Expense.methods.include?("valid?") # => false
assert !ActiveRecord::Base.methods.include?("valid?") # => false
assert !ActiveRecord::Validations.methods.include?("valid?") # =>

```

false  
assert expense.is\_a?(ActiveRecord::Base) # =\> true  
assert expense.is\_a?(ActiveRecord::Validations) # =\> true  
end

Inoltre ho provato a eseguire il codice step-by-step col debugger, ma  
quando faccio step-in nel metodo “valid?” finisco in  
vendor/rails/activerecord/lib/active\_record/callbacks.rb:295:in `valid?’  
che invece Ã¨ il metodo valid\_with\_callbacks? del modulo  
ActiveRecord::Callbacks

Potete aiutarmi? grazie

---

<div class="post-metadata">

**Author:** ![Gian\_marco\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/f475e1/32.png) [@Gian\_marco\_G](https://www.ruby-forum.com/u/Gian_marco_G)\
**Post date:** [September 10, 2007, 12:28am UTC](https://www.ruby-forum.com/t/rails-come-mai-la-mia-classe-risponde-al-metodo-valid/114211/2 "2007-09-10T00:28:22Z")

</div>

— Gian marco Gherardi [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> def test\_required\_fields  
> expense = Expense.new  
> assert expense.valid?  
> end  
> end
> 
> Il test passa ma non riesco a capire dove è definito  
> il metodo “valid?”

lo autodefinisce ActiveRecord automaticamente, come  
#save etc, modifica #validate per aggiungere  
funzionalità direttamente invece di usare il DSL di  
validazione

```
  ___________________________________________________________

```

Want ideas for reducing your carbon footprint? Visit Yahoo! For Good  
[http://uk.promotions.yahoo.com/forgood/environment.html](http://uk.promotions.yahoo.com/forgood/environment.html)

---

<div class="post-metadata">

**Author:** ![Gian\_marco\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/f475e1/32.png) [@Gian\_marco\_G](https://www.ruby-forum.com/u/Gian_marco_G)\
**Post date:** [September 10, 2007, 9:02am UTC](https://www.ruby-forum.com/t/rails-come-mai-la-mia-classe-risponde-al-metodo-valid/114211/3 "2007-09-10T09:02:08Z")

</div>

— gabriele renzi [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> modifica #validate per aggiungere  
> funzionalità direttamente invece di usare il DSL di  
> validazione

leggasi "se vuoi, definisci il metodo #validate per  
implementare la tua logica di validazione  
direttamentese hai bisogno di qualcosa non  
reealizzabile con i vari validates\_\* "

```
  ___________________________________________________________

```

Want ideas for reducing your carbon footprint? Visit Yahoo! For Good  
[http://uk.promotions.yahoo.com/forgood/environment.html](http://uk.promotions.yahoo.com/forgood/environment.html)

---

<div class="post-metadata">

**Author:** ![Gian\_marco\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/f475e1/32.png) [@Gian\_marco\_G](https://www.ruby-forum.com/u/Gian_marco_G)\
**Post date:** [September 10, 2007, 12:32pm UTC](https://www.ruby-forum.com/t/rails-come-mai-la-mia-classe-risponde-al-metodo-valid/114211/4 "2007-09-10T12:32:53Z")

</div>

Luca G. wrote:

> In ActiveRecord::Base. Il carattere ‘\<’ indica che Expense “eredita”  
> dalla classe su citata, l’equivalente in Java Ã¨ ‘extends’.  
> Fa parte del modulo ActiveRecord::Validations, e se ti interessa  
> studiarne il codice, Ã¨ nel file validations.rb:777.
> 
> –  
> blog: [www.lucaguidi.com](http://www.lucaguidi.com)
> 
> Bringing Rails to Italy  
> First italian Ruby On Rails conference:  
> Oct, 26-27 2007 - Pisa  
> [www.railstoitaly.org](http://www.railstoitaly.org)

Non riesco ancora a trovare in che modo la classe

Expense \< ActiveRecord::Base

Ã¨ legata al modulo

ActiveRecord::Validations

Mi aspetterei di trovare nel codice sorgente di ActiveRecord::Base la  
riga

include Validations

Ma non la riesco a trovare. Sto cercando la cosa sbagliata?

---

<div class="post-metadata">

**Author:** ![Gian\_marco\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/f475e1/32.png) [@Gian\_marco\_G](https://www.ruby-forum.com/u/Gian_marco_G)\
**Post date:** [September 10, 2007, 9:39am UTC](https://www.ruby-forum.com/t/rails-come-mai-la-mia-classe-risponde-al-metodo-valid/114211/5 "2007-09-10T09:39:10Z")

</div>

In ActiveRecord::Base. Il carattere ‘\<’ indica che Expense “eredita”  
dalla classe su citata, l’equivalente in Java Ã¨ ‘extends’.  
Fa parte del modulo ActiveRecord::Validations, e se ti interessa  
studiarne il codice, Ã¨ nel file validations.rb:777.

–  
blog: [www.lucaguidi.com](http://www.lucaguidi.com)

Bringing Rails to Italy  
First italian Ruby On Rails conference:  
Oct, 26-27 2007 - Pisa  
[www.railstoitaly.org](http://www.railstoitaly.org)

---

<div class="post-metadata">

**Author:** ![Gian\_marco\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/f475e1/32.png) [@Gian\_marco\_G](https://www.ruby-forum.com/u/Gian_marco_G)\
**Post date:** [September 10, 2007, 9:22pm UTC](https://www.ruby-forum.com/t/rails-come-mai-la-mia-classe-risponde-al-metodo-valid/114211/6 "2007-09-10T21:22:29Z")

</div>

Luca G. wrote:

> Nel file active\_record.rb:58  
> include ActiveRecord::Validations  
> E’ posto all’interno del blocco passato ad  
> ActiveRecord::Base.class\_eval.
> 
> Nel file validation.rb c’Ã¨ l’override del metodo included, che effettua  
> l’injection del codice vero e proprio.
> 
> Per capire come funziona il meccanismo ti rimando all’API-DOC del  
> linguaggio ([class Module - RDoc Documentation](http://www.ruby-doc.org/core/classes/Module.html#M001683)).

Con le tue indicazioni ho cercato di capire cosa succede. Riporto  
qui il codice coninvolto nel problema, arricchito di commenti.

Adesso mi Ã¨ tutto un pÃ² piu chiaro, grazie!

File: active\_record.rb

# …

ActiveRecord::Base.class\_eval do  
include ActiveRecord::Validations  
# …  
include ActiveRecord::Callbacks  
# …  
end

# …

File: validations.rb  
module ActiveRecord  
# …  
module Validations  
# …  
def valid?  
errors.clear  
run\_validations(:validate)  
validate  
if new\_record?  
run\_validations(:validate\_on\_create)  
validate\_on\_create  
else  
run\_validations(:validate\_on\_update)  
validate\_on\_update  
end  
errors.empty?  
end  
# …  
end  
end

File: callbacks.rb  
module ActiveRecord  
# …  
module Callbacks  
# …  
# questo metodo viene invocato su ActiveRecord::Callbacks  
# dalla chiamata class\_eval sopra, passando come parametro  
# ActiveRecord::Base  
def self.included(base)  
# alla classe ActiveRecord::Base vengono iniettati i  
# metodi di ClassMethods, come metodi di classe (statici)  
base.extend(ClassMethods)  
base.class\_eval do  
class \<\< self  
include Observable  
alias\_method\_chain :instantiate, :callbacks  
end  
# all’interno del ciclo qui sotto:  
# crea un nuovo alias valid\_without\_callbacks?  
# dal metodo (giÃ presente) valid?.  
# creo un nuovo alilas valid? (sovrascrivendo il metodo  
# valid?) di valid\_with\_callbacks?  
# questo spiega perchÃ¨ facendo step-in col debugger  
# in corrispondenza della chiamata al metodo valid?  
# finivo nella definizione di valid\_with\_callbacks?  
[:initialize, :create\_or\_update, :valid?, :create, :update,  
:destroy].each do |method|  
alias\_method\_chain method, :callbacks  
end  
end  
# …  
end  
# …  
module ClassMethods  
# …  
end  
# …  
end  
# …  
end

---

<div class="post-metadata">

**Author:** ![Gian\_marco\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/f475e1/32.png) [@Gian\_marco\_G](https://www.ruby-forum.com/u/Gian_marco_G)\
**Post date:** [September 10, 2007, 1:45pm UTC](https://www.ruby-forum.com/t/rails-come-mai-la-mia-classe-risponde-al-metodo-valid/114211/7 "2007-09-10T13:45:49Z")

</div>

Nel file active\_record.rb:58  
include ActiveRecord::Validations  
E’ posto all’interno del blocco passato ad  
ActiveRecord::Base.class\_eval.

Nel file validation.rb c’Ã¨ l’override del metodo included, che effettua  
l’injection del codice vero e proprio.

Per capire come funziona il meccanismo ti rimando all’API-DOC del  
linguaggio ([class Module - RDoc Documentation](http://www.ruby-doc.org/core/classes/Module.html#M001683)).

–  
blog: [www.lucaguidi.com](http://www.lucaguidi.com)

Bringing Rails to Italy  
First italian Ruby On Rails conference:  
Oct, 26-27 2007 - Pisa  
[www.railstoitaly.org](http://www.railstoitaly.org)
