se parliamo di validazione, devi rivolgere l’attenzione a quello che
avviene NEL modello. quindi se i due controller trattano in modo
differente lo stesso modello, dovrai basare la validazione su quelle
differenze.
se non ci sono differenze, magari puoi usare un solo controller e butti
quello che avanza…
Sistema grezzo: in un controller inizializzi una variabile e sull’altro
no (o la crei su entrambi dandole valori diversi) e tramite un ciclo if
controlli se è presente (o che valore ha) e nel caso gli fai eseguire
quello che ti serve.
Se non c’è niente di più elegante, penso sia l’unica soluzione.
se parliamo di validazione, devi rivolgere l’attenzione a quello che
avviene NEL modello. quindi se i due controller trattano in modo
differente lo stesso modello, dovrai basare la validazione su quelle
differenze.
se non ci sono differenze, magari puoi usare un solo controller e butti
quello che avanza…
Sistema grezzo: in un controller inizializzi una variabile e sull’altro
no (o la crei su entrambi dandole valori diversi) e tramite un ciclo if
controlli se è presente (o che valore ha) e nel caso gli fai eseguire
quello che ti serve.
Se non c’è niente di più elegante, penso sia l’unica soluzione.
si questo � chiaro. quello che ho cercato di dirti � per fare qualcosa
del genere devi focalizzarti sul valore del campo nel modello.
in altre parole, � un po’ assurdo fare validazioni (quindi parliamo di
Model) regolandoti sul Controller usato.
se vuoi farlo, una strada � quella che ti ha indicato Daneel, che � pi�
o meno quello che ti stavo dicendo io (cio� controllare per un
determinato campo, e decidere in base al suo valore se validare o no)
si questo è chiaro. quello che ho cercato di dirti è per fare qualcosa
del genere devi focalizzarti sul valore del campo nel modello.
in altre parole, è un po’ assurdo fare validazioni (quindi parliamo di
Model) regolandoti sul Controller usato.
se vuoi farlo, una strada è quella che ti ha indicato Daneel, che è più
o meno quello che ti stavo dicendo io (cioè controllare per un
determinato campo, e decidere in base al suo valore se validare o no)
ti ho messo un pezzo di codice nell’altra risposta, comunque a grandi
linee funziona
così:
validates_presence_of :campo_che_ti_pare, :if => Proc.new {|m|
m.campo_da_controllare == qualche_valore}
in altre parole, è possibile passare una condizione alla validazione per
decidere se eseguirla o meno. puoi usare sia :if che :unless ed
ovviamente è usabile anche per altri metodi di validazione
inoltre non occorre sovrascrivere il costruttore, nè mettere gli
attributi di accesso. basta averlo sul db. in caso puoi creare un campo fake ma non è la soluzione più veloce
inoltre non occorre sovrascrivere il costruttore, n� mettere gli
attributi di accesso. basta averlo sul db. in caso puoi creare un campo fake ma non � la soluzione pi� veloce
ciao,
A.
Il 23/06/2010 16:47, pezzuya … ha scritto:
ma con attr_accessor non ho creato un attributo virtuale? (esegui)
perchè c’è la necessità di creare un campo sul db?
dipende come devi accedere a quell’attributo, spesso devi far credere ad
ActiveRecord di avere quei campi su una tabella (per esempio quando vuoi
applicargli le validazioni), in quel caso crei dei campi fake in un
altro modo.
nel tuo caso, se proprio vuoi farlo così, prova:
attr_accessor :esegui
def initialize(params = nil)
self.esegui = true
super
end
la spiegazione è che quando crei un’istanza di una classe derivata da
ActiveRecord::Base necessariamente in fase di costruzione deve
conoscere i campi della tabella che rappresenta, altrimenti come fa a
sapere quali attributi ha un certo modello?
queste operazioni avvengono, di norma, nella fase di costruzione
dell’oggetto, quindi “initialize”. quando dichiari il metodo initialize
nel modello, di fatto stai sovrascrivendo un comportamento di default: è
lecito farlo, ma poi devi chiamare anche il metodo originario,
dichiarato in qualche classe-padre, per inizializzare l’oggetto come
previsto.
perciò non stai agendo su quel metodo, lo chiami e basta
tanto per completare, spesso può essere necessario farlo anche quando
sovrascrivi un metodo setter, per esempio se hai un attributo ‘name’
in un modello ma vuoi che faccia qualcosa di diverso dal previsto quando
imposti un valore su quel campo:
dipende come devi accedere a quell’attributo, spesso devi far credere ad
ActiveRecord di avere quei campi su una tabella (per esempio quando vuoi
applicargli le validazioni), in quel caso crei dei campi fake in un
altro modo.
nel tuo caso, se proprio vuoi farlo cos�, prova:
attr_accessor :esegui
def initialize(params = nil)
self.esegui = true
super
end
cio� chiami il costruttore originale con ‘super’
Mi pare di capire che tu abbia già risolto il problema grazie all’aiuto
dei partecipanti alla discussione, pertanto se ti andava volevo
filosofeggiare un pochino sul tuo problema: come mai ti ritrovi a voler
eseguire le validazioni sul modello su un controller e no su un altro?
Voglio dire, è una situazione un po’ strana: nulla vieta infatti al
controller coi superpoteri di creare record invalidi nel db, cosa che mi
sembra potenzialmente pericolosa.
Ah, un’altra possibile soluzione al problema credo sarebbe potuta essere
sfruttare la single table inheritance: ti crei un modello base con due
sottomodelli, tipo questi:
class Document
end
class PossiblyInvalidDocument #no validations here
end
class DefinitelyValidDocument
validates_presence_of :text
other validations
end
e poi nei controller crei il tipo di documento che ti serve.
la spiegazione � che quando crei un’istanza di una classe derivata da
ActiveRecord::Base necessariamente in fase di costruzione deve
conoscere i campi della tabella che rappresenta, altrimenti come fa a
sapere quali attributi ha un certo modello?
queste operazioni avvengono, di norma, nella fase di costruzione
dell’oggetto, quindi “initialize”. quando dichiari il metodo initialize
nel modello, di fatto stai sovrascrivendo un comportamento di default: �
lecito farlo, ma poi devi chiamare anche il metodo originario,
dichiarato in qualche classe-padre, per inizializzare l’oggetto come
previsto.
perci� non stai agendo su quel metodo, lo chiami e basta
tanto per completare, spesso pu� essere necessario farlo anche quando
sovrascrivi un metodo setter, per esempio se hai un attributo ‘name’
in un modello ma vuoi che faccia qualcosa di diverso dal previsto quando
imposti un valore su quel campo:
Mi pare di capire che tu abbia già risolto il problema grazie all’aiuto
dei partecipanti alla discussione, pertanto se ti andava volevo
filosofeggiare un pochino sul tuo problema: come mai ti ritrovi a voler
eseguire le validazioni sul modello su un controller e no su un altro?
Voglio dire, è una situazione un po’ strana: nulla vieta infatti al
controller coi superpoteri di creare record invalidi nel db, cosa che mi
sembra potenzialmente pericolosa.
Ah, un’altra possibile soluzione al problema credo sarebbe potuta essere
sfruttare la single table inheritance: ti crei un modello base con due
sottomodelli, tipo questi:
class Document
end
class PossiblyInvalidDocument #no validations here
end
class DefinitelyValidDocument
validates_presence_of :text
other validations
end
e poi nei controller crei il tipo di documento che ti serve.
Ciao
Andrea
Mi serviva perchè avevo due controller che condividevano lo stasso
modello. In un caso dovevo effettuare una validazione sul formato del
file caricato mentre nell’altro no (me lo avevano richiesto
esplicitamente). L’utilizzo dell’ereditarietà tra modelli l’avevo giÃ
pensata e utilizzata in un’altra occasione e resta secondo me la
soluzione “più pulita”. Però in questo caso mi tornava utile “andare
sullo sporco” per 1)imparare qualcosa di nuovo 2)evitare di andare a
toccare cose che erano già testate e funzionanti.
Mi serviva perchè avevo due controller che condividevano lo stasso
modello. In un caso dovevo effettuare una validazione sul formato del
file caricato mentre nell’altro no (me lo avevano richiesto
esplicitamente).
Ma come mai ti hanno fatto una richiesta simile? Ci sono motivazioni
reali? Voglio dire, è lecito che il cliente mi chieda qualsiasi
porcheria, io poi gli rispondo che così no non va bene, ovviamente se
poi insiste faccio come vuole lui, visto che mi paga, ma c’è da stare
attenti.
Gli devo dire anche che oggi il codice funziona, sembra non creare
particolari problemi (se il fatto di accettare record non validati non è
un problema) ma è facile che codice come questo prima o poi ti morda la
mano, e il malaugurato giorno che ci sarà da modificare qualcosa o
fixare il problema potrebbe volerci molto più tempo (e quindi denaro da
parte sua), e che quindi io me ne lavo le mani… uomo avvistato mezzo
salvato.