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 <http://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í ?
_______________________________________________ Ruby mailing list [email protected] http://lista.rubyargentina.com.ar/listinfo.cgi/ruby-rubyargentina.com.ar
