Ciao a tutti, mi trovo ad affrontare un problema con rails che non ho mai affrontato e mi piacerebbe sapere qual' il metodo pi giusto per risolverlo :) Vi espongo il problema: nell'app c' un modello "Persona", che potrebbe trovarsi in queste situazioni: - essere e rimanere sempre soltanto una persona - diventare uno "Studente", quindi acquisire nuovi attributi (tipo n. di matricola), mantenendo quelli di "Persona" - diventare un "Pendolare", anche in questo caso acquisendo nuovi attributi (tipo n. di abbonamento) mantenendo quelli di persona - diventare sia uno studente che un pendolare, rimanendo una persona ma acquisendo gli attributi sia di uno studente che di un pendolare il tutto ovviamente in rails, quindi con validazioni, relazioni, ecc. Al volo la soluzione che mi sarebbe venuta in mente quella di fare un modello Persona che ha una relazione 1-1 con Pendolare e con Studente, ma in questo modo sto trattando i tre modelli come entit veramente separate, mentre logicamente non lo dovrebbero essere. Inoltre dovrei, presa una persona, richiedere un dato di studente con "persona.studente.n_matricola", mentre sarebbe ottimo fare "persona.n_matricola" che mi restituisce false o nil se la persona non uno studente Esiste in rails "qualcosa" per fare quello che devo fare? se ho chiesto una cosa banale accetto anche infamate, sempre che siano accompagnate da un link da leggermi! :)
on 2012-06-05 21:37
on 2012-06-05 22:32
Persona e pendolare sono due variabili boolean... Io farei cosi... Ma soni grezzo Il giorno 05/giu/2012 21:37, "Tommaso Visconti" <tommaso.visconti@gmail.com> ha scritto:
on 2012-06-05 22:49
Ciao,
la tua intuizione mi sembra corretta, ma userei dei nomi diversi per
evitare confusione. Il concetto che tu hai un modello
Persona che si pu arricchire di diverse abilit a seconda del proprio
stato. Farei una cosa del genere:
class Person
has_one :student_ability
has_one :pendular_ability
end
Ovviamente has_one ha senso solo se gli altri modelli istanze di
ActiveRecord, altrimenti ti basta una cosa del genere:
class Person
def student_ability
StudentAbility.new(self)
end
...
end
Dopo di che puoi delegare dal modello Person verso i rispettivi oggetti
di cui si compone:
class Person
delegate :n_matricola, :to => :student_ability
...
end
che per solleva una eccezione se il modello student_ability nil.
on 2012-06-05 23:26
---- Riccardo Il giorno 05/giu/2012, alle ore 23:12, Emanuele DelBono <emanuele.delbono@gmail.com> ha scritto: > Ma voi non usereste un Decorator Pattern? Ma poi come lo mappo ? > > +1 Stessa idea stesso dubbio
on 2012-06-06 00:36
class Person
attr_accessor :name
end
module Behaviors
module Student
def registration_number # write me
end
end
module Pendular
def subscription_number # write me
end
end
end
tizio = Person.new
tizio.extend Behaviors::Student
tizio.registration_number
caio = Person.new
caio.extend Behaviors::Pendular
caio.subscription_number
E' un'eresia?
Ovviamente, questi sarebbero solo PORO ma persisterli non dovrebbe
essere
impossibile.
Maurizio
--
My profile <https://plus.google.com/100973969013103507046/about>
2012/6/5 Riccardo Lucatuorto <gnuduncan@gmail.com>
on 2012-06-06 08:46
Non conoscevo il metodo extend...e quando vedo questo codice mi emoziono. <3 ruby! 2012/6/6 maurizio de magnis <maurizio.demagnis@gmail.com>:
on 2012-06-06 08:55
Domande... Non meglio fare due moduli separati? possibile gi in un modulo inserire qualche riferimento ad activerecord in modo che mappi i campi da se? possibile invertire la cosa? Mi spigo... Fare un modulo Persona da includere in 3 classi: Studente, Pendolare e StudentePendolare? ---- Riccardo Il giorno 06/giu/2012, alle ore 00:36, maurizio de magnis <maurizio.demagnis@gmail.com> ha scritto:
on 2012-06-06 09:54
Non userei dei moduli in questo caso, a meno che non si debba condividere il comportamento tra due classi, ma qui la classe Person una sola. Non sarebbe diverso dal mettere i metodi direttamente nella classe, non vedo benefici, i metodi conditnuano a condividere le variabili di istanza e le responsabilit della classe non diminuiscono.
on 2012-06-06 10:05
On Wed, Jun 6, 2012 at 9:47 AM, Fabrizio Regini <freegenie@gmail.com> wrote: > Che vuoi dire? > Intendevo che una volta creata la struttura per implementare un Decorator, riesco a persisterla con ActiveRecord? (con NHibernate ce la faccio, con RoR non so...) ema http://blog.codiceplastico.com/ema
on 2012-06-06 10:26
2012/6/6 Fabrizio Regini <freegenie@gmail.com> > Non userei dei moduli in questo caso, a meno che non si debba condividere > il comportamento tra due classi, ma qui la classe Person una sola. > Non sarebbe diverso dal mettere i metodi direttamente nella classe, non > vedo benefici, i metodi conditnuano a condividere le variabili di istanza e > le responsabilit della classe non diminuiscono. Pensavo alla transizioni che avverrebbero in un oggetto inizialmente Person, poi augmentato con il behavior di Student e successivamente di Pendular. class Person def augment(behavior) extend Behaviors.const_get(behavior) end end pinky = Person.new # pinky now goes to school! pinky.augment :Student pinky.respond_to? :registration_number # => true # pinky now uses public transports! pinky.augment :Pendular pinky.respond_to? :subscription_number # => true Ovviamente, nell'ipotesi che questi stati non siano mutuamente esclusivi. Maurizio -- My profile <https://plus.google.com/100973969013103507046/about>
on 2012-06-06 10:55
Interessante. Non ho mai usato questo livello di metaprogrammazione per risolvere un problema del genere.
on 2012-06-06 12:08
Forse sono rimasto indietro con rails. che ormai fa cose che voi umani non potreste immaginare, ma rimane la relazione modello==tabella giusto? E come implementi il polimorfismo in una tabella MySQL? Personalmente, parto da questo assunto (sbagliato?): e' impossibile implementare il polimorfismo con tabelle MySQL. Di conseguenza servono degli escamotage. Delle soluzioni proposte (scusate la mia risposta criptica: rispondevo da mobile e ho le dita grosse) Questa mi sembra la pi semplice da implementare: class Person has_one :student_ability has_one :pendular_ability end (quella di Fabrizio Regini) Ricordandosi ovviamente di considerare il caso in cui student_ability e' nil Ciao!
on 2012-06-06 12:33
Maurizio De magnis wrote in post #1063303:
[CUT]
Complimenti per la soluzione però non mi sembra utile, da qualche parte
devi memorizzarle quelle informazioni ...o sai qualcosa che io non so???
(chiedo, dopo quell magia non si sa mai)
Secondo me l'unica fattibile è la relazione 1-1, la prima proposta da
Fabrizio. Se l'eccezione del delegate è un problema puoi sempre
definirti tu i metodi:
class Person
def n_matricola
self.student.try :n_matricola
end
end
on 2012-06-06 12:50
Il 06/06/12 12:33, Marco Mastrodonato ha scritto: > Complimenti per la soluzione per non mi sembra utile, da qualche parte > devi memorizzarle quelle informazioni ...o sai qualcosa che io non so??? > (chiedo, dopo quell magia non si sa mai) Le varie soluzioni sono molto interessanti, ma quel che mi preoccupa proprio il rapporto con activerecord e il db. Anche a me la 1-1 mi sembra la pi "pulita" per quanto riguarda poi la persistenza dei dati senza dover scrivere un sacco di codice nel modello Person > Secondo me l'unica fattibile la relazione 1-1, la prima proposta da > Fabrizio. Se l'eccezione del delegate un problema puoi sempre > definirti tu i metodi: > > class Person > def n_matricola > self.student.try :n_matricola > end > end > Credo che il parametro :allow_nil => true di delegate eviti proprio l'eccezione indicata da fabrizio: class Person delegate :n_matricola, :to => :student_ability, :allow_nil => true ... end http://api.rubyonrails.org/classes/Module.html#met...
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.