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

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

— Gian marco Gherardi [email protected]
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

— gabriele renzi [email protected] 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

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

Bringing Rails to Italy
First italian Ruby On Rails conference:
Oct, 26-27 2007 - Pisa
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?

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

Bringing Rails to Italy
First italian Ruby On Rails conference:
Oct, 26-27 2007 - Pisa
www.railstoitaly.org

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

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

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


blog: www.lucaguidi.com

Bringing Rails to Italy
First italian Ruby On Rails conference:
Oct, 26-27 2007 - Pisa
www.railstoitaly.org