2009/10/3 Nicolás Sanguinetti <[email protected]> > Sigh, por que no haces lo de poner el include/extend en cada modelo? > > 2009/10/3 Martin Aceto <[email protected]>: > > > > > > 2009/10/3 Nicolás Sanguinetti <[email protected]> > >> > >> 2009/10/3 Martin Aceto <[email protected]>: > >> > > >> > > >> >> 2009/10/3 Martin Aceto <[email protected]>: > >> >> > > >> >> > > >> >> > 2009/10/3 Nelson Fernandez <[email protected]> > >> >> >> > >> >> >> 2009/10/3 Martin Aceto <[email protected]> > >> >> >>> > >> >> >>> 2009/10/3 Nelson Fernandez <[email protected]> > >> >> >>>> > >> >> >>>> Martin ! > >> >> >>>> > >> >> >>>> 2009/10/2 Martin Aceto <[email protected]> > >> >> >>>>> > >> >> >>>>> Hola, como estan > >> >> >>>>> > >> >> >>>>> estoy tratando de extender activerecord para poder sacar de un > >> >> >>>>> modelo > >> >> >>>>> logica que no pertenece a ese modelo sino que engloba varios > >> >> >>>>> modelos, logica > >> >> >>>>> de negocio bastante complicada que desearia separar. > >> >> >>>>> > >> >> >>>>> Me encuentro con la pregunta de cual es la forma correcta de > >> >> >>>>> hacerlo > >> >> >>>>> ? > >> >> >>>>> > >> >> >>>>> Lo que pense fue crear un archivo en /lib y dentro definir esos > >> >> >>>>> metodos > >> >> >>>>> que necesito, este ejemplo de abajo es correcto ? o estoy > >> >> >>>>> equivocado > >> >> >>>>> en mi > >> >> >>>>> concepto ? > >> >> >>>>> > >> >> >>>>> module Test > >> >> >>>>> module ClassMethods > >> >> >>>>> def test > >> >> >>>>> puts "Test" > >> >> >>>>> end > >> >> >>>>> end > >> >> >>>>> end > >> >> >>>>> > >> >> >>>>> ActiveRecord::Base.send(:extend, Test::ClassMethods) > >> >> >>>> > >> >> >>>> > >> >> >>>> Comparto con Emanuel de usar la menos magia posible .. quizás > otra > >> >> >>>> solución simple sea usar mixins [1] ?. > >> >> >>>> > >> >> >>>> [1] http://www.rubycentral.com/pickaxe/tut_modules.html#S2 > >> >> >>>> > >> >> >>>> > >> >> >>>> -- > >> >> >>>> :: nelson :: > >> >> >>>> [ artesano de software & software craftsman ] > >> >> >>>> http://netflux.com.ar > >> >> >>>> > >> >> >>>> > >> >> >>>> > >> >> >>> > >> >> >>> Leí el enlace que mandaste Nelson, si es mas simple, esta bueno. > >> >> >>> Pero > >> >> >>> quiero extender ActiveRecord para poder tener esos metodos en > todas > >> >> >>> las > >> >> >>> clases, estoy intentando hacer esto como dijo Emmanuel > >> >> >>> > >> >> >>> module Test > >> >> >>> > >> >> >>> module ClassMethods > >> >> >>> > >> >> >>> def test > >> >> >>> puts "Test" > >> >> >>> end > >> >> >>> > >> >> >>> end > >> >> >>> > >> >> >>> end > >> >> >>> > >> >> >>> ActiveRecord::Base.extend, Test::ClassMethods > >> >> >>> ActiveRecord::Base.class_eval do > >> >> >>> include Test::InstanceMethods > >> >> >>> end > >> >> >>> > >> >> >>> pero no me funciona, y no entiendo porque, pero si incluyo > >> >> >>> directamente > >> >> >>> en una clase de esta manera > >> >> >>> > >> >> >> > >> >> >> > >> >> >> "extend" es para agregar los métodos de un modulo a una > "instancia", > >> >> >> no > >> >> >> a > >> >> >> una clase. > >> >> >> Lo que está haciendo "ActiveRecord::Base.extend > Test::ClassMethods" > >> >> >> es > >> >> >> extender el objeto que implementa Class... en el caso práctico > estás > >> >> >> agregando métodos de clase, es decir que lo que va a funcionar es > >> >> >> > >> >> >> ActiveRecord::Base.test > >> >> >> o > >> >> >> MyModelo.test > >> >> >> > >> >> >> que no es lo que estas buscando, creo... sino que las instancias > de > >> >> >> ActiveRecord tengan tus nuevos métodos. > >> >> >> > >> >> >> Para mí la forma más simple y clara nuevamente es usar mixins y de > >> >> >> esa > >> >> >> forma queda muy claro que modelos van a tener esa funcionalidad > >> >> >> agregada. > >> >> >> > >> >> >> > >> >> >> > >> >> >> PD: Te recomiendo ver este video donde Dave Thomas explica el > modelo > >> >> >> de > >> >> >> objetos de Ruby > >> >> >> > >> >> >> http://scotland-on-rails.s3.amazonaws.com/2A04_DaveThomas-SOR.mp4 > >> >> >> > >> >> >> y este muy gracioso cuando Joe OBrian quiere usar metaprograming a > >> >> >> toda > >> >> >> costa ;) > >> >> >> > >> >> >> > >> >> >> > >> >> >> > http://scotland-on-rails.s3.amazonaws.com/2A08_JoeOBrianJimWeirich-SOR.mp4 > >> >> >> > >> >> >> > >> >> > > >> >> > Nelson, lo que estoy intentando hacer, como vos dijiste, es > extender > >> >> > el > >> >> > objeto que implementa Class y poder hacer > >> >> > > >> >> > ActiveRecord::Base.test > >> >> > o > >> >> > MyModelo.test > >> >> > pero no se porque no me funciona. > >> >> > > >> >> > Gracias > >> >> > > >> >> > >> > 2009/10/3 Nicolás Sanguinetti <[email protected]> > >> > > >> > Primero (y hago top posting porque recien me levante, tengo sueño, y > >> > soy re heavy re jodido :P) lo que decía Emmanuel sobre "clases > >> > específicas" no es que si lo vas a usar en *una sola clase*, sino en > >> > *algunas* clases especificas. Ponele que tenés una aplicación chica, > >> > con no sé, 10 modelos. > >> > > >> > Si vos querés extraer una funcionalidad a algo que se comparte entre 4 > >> > o 5 de ellos, hacer ActiveRecord::Base.extend(MyAwesomeMixin) es > >> > chancho. Le > >> > estás encajando métodos a 5 o 6 modelos que no tienen nada > >> >> > >> >> que ver con eso. > >> >> > >> >> Entonces lo prolijo sería hacer el "include" o "extend" en cada uno > de > >> >> los 4 o 5 modelos que necesitan MyAwesomeMixin. > >> >> > >> >> class User < AR::B > >> >> include Foo > >> >> end > >> >> > >> >> class Thing < AR::B > >> >> include Foo > >> >> end > >> >> > >> >> etc. > >> >> > >> >> Segundo, si vos lo que querés es agregar métodos de clase compartidos > >> >> entre varios modelos (por ejemplo, finders, métodos de search, etc), > >> >> lo que querés hacer es extend, sí. > >> >> > >> >> class User < AR::B > >> >> extend FooBar > >> >> end > >> >> > >> >> Si estás haciendo esto (como entiendo de tu primer post) y no > >> >> funciona, entonces va a ser mejor que hagas un paste con código "más > >> >> de verdad" para entender dónde está el problema. Por que lo que vos > >> >> pegaste arriba, tiene que andar. > >> >> > >> >> (Ojo al gol, si vos ponés un 'puts' en un modelo, el output lo vas a > >> >> ver en el mismo output que tu server si usas mongrel/thin/etc, o no > lo > >> >> vás a ver nada si usás passenger—capaz que el problema es ese? Probá > >> >> poner Rails.logger.info("---------> test") y fijarte si no aparece > en > >> >> el log) > >> >> > >> >> -f > >> > > >> > > >> > Hola Nicolas, entiendo lo que decis de que extender ActiveRecord para > >> > todos > >> > los modelos cuando solo la mitad o menos usaran esos metodos, es > chanco, > >> > por > >> > lo cual voy a utilizar include o extend en los modelos que necesito > esos > >> > metodos especificos. > >> > > >> > Pero de todas estas preguntas y respuestas me quede con la intriga de > >> > como > >> > hacer para extender ActiveRecord para agregar, finders, metodos de > >> > search, > >> > etc... para toda la aplicación, por eso les comente que no me > funcionaba > >> > esto > >> > > >> > > >> > module Test > >> > module ClassMethods > >> > def test > >> > puts "Test" > >> > end > >> > end > >> > end > >> > > >> > ActiveRecord::Base.extend, Test::ClassMethods > >> > ActiveRecord::Base.class_eval do > >> > include Test::InstanceMethods > >> > end > >> > > >> > (todo mi codigo se reduce a esto) solo una simple prueba > >> > > >> > por lo que yo entendi con ese codigo de arriba podria hacer en una > >> > consola > >> > para cualquier modelo del app, como por ejemplo User > >> > > >> > User.test > >> > > >> > y me daria el texto "text". > >> > Esto sin hacer ningún include o extend dentro de User, no es así ? > >> > >> Ah, pará, vos dijiste que pusiste el código en lib, no? > >> > >> En dónde estás haciendo los llamados a extend? Si es desde el mismo > >> archivo, tenés que, en algún lado, requerir ese archivo. Rails no > >> requiere todos los archivos, los requiere a medida que se necesitan, y > >> el mecanismo para saber eso es según nombres de constantes. > >> > >> Si vos pedís Foo en algún lado se va a fijar por app/models/foo.rb, > >> lib/foo.rb, vendor/gems/*/lib/foo.rb, vendor/plugins/*/lib/foo.rb. > >> (Creo que en ese orden, pero tampoco es importante). > >> > >> El tema es que si vos directamente llamás al método en el modelo, sin > >> haber requerido antes el archivo, no va a andar :) > >> > >> Si lo vás a extender explicitamente en los modelos, al hacer > >> > >> class User > >> extend MyAwesomeMixin > >> end > >> > >> estás referenciando la constante, y por ende haciendo que rails > >> requiera el archivo (en cuyo caso va a funcionar). > >> > >> Pero si querés que lo meta en todos los archivos, entonces el > >> ActiveRecord::Base.extend(MyAwesomeMixin) tendrías que ponerlo en un > >> initializer, en config/initializers/my_awesome_mixin.rb -- eso se > >> asegura de que todos los modelos tengan esos métodos cuando inicia el > >> framework. > >> > >> Saludos, > >> -f > >> > >> > > > > Ahi funciono, me faltaba saber eso, no estaba requeriendo el archivo y > por > > eso no lo tenia disponible en todos los modelos, ahora me quedo > > > > config/initializers/extend_ar.rb > > > > ActiveRecord::Base.extend(Test::ClassMethods) > > ActiveRecord::Base.class_eval do > > include Test::InstanceMethods > > end > > > > y en lib/test.rb > > > > module Test > > module ClassMethods > > def test > > puts "Test" > > end > > end > > > > module InstanceMethods > > end > > end > > > > y funciona perfecto ! > > > > Tenes idea donde esta en la doc de rails esto de que se tiene que > requerir > > el archivo para que haga el extend ? tendria que leerla. > > > > Gracias Nicolas > > >
Si voy a usar el inlcude/extend en cada modelo que necesite agregar metodos espesificos, pero queria saber como funcionaba extender ActiveRecord sin usar un plugin o include/extend en el modelo Gracias por la ayuda.
_______________________________________________ Ruby mailing list [email protected] http://lista.rubyargentina.com.ar/listinfo.cgi/ruby-rubyargentina.com.ar
