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

Responder a