Tengo una situación en mi aplicación Rails donde necesito incluir módulos arbitrarios dependiendo del estado actual del tiempo de ejecución. El módulo proporciona código de aplicación personalizado que solo es necesario cuando ciertas condiciones son verdaderas. Básicamente, estoy tirando el nombre de una empresa a partir del contexto actual y el uso que, como el nombre del archivo para el módulo y su definición:Ruby: incluya un nombre de módulo dinámico
p = self.user.company.subdomain + ".rb"
if File.exists?(Rails.root + "lib/" + p)
include self.class.const_get(self.user.company.subdomain.capitalize.to_sym)
self.custom_add_url
end
Mi módulo de prueba es el siguiente:
module Companyx
def custom_add_url
puts "Calling custom_add_url"
end
end
Ahora en la consola, esto realmente funciona bien. Puedo tirar de un usuario e incluir el módulo de esta manera:
[1] pry(main)> c = Card.find_by_personal_url("username")
[2] pry(main)> include c.class.const_get(c.user.company.subdomain.capitalize)=> Object
[3] pry(main)> c.custom_add_url
Calling custom_add_url
Si trato de ejecutar la línea de incluir de mi modelo, consigo
NoMethodError: undefined method `include' for #<Card:0x007f91f9094fb0>
¿Puede alguien sugerir qué la instrucción include funcionaría en la consola, pero no en mi código modelo?
Cambiar el contexto parece agregar una complicación: el autoobjeto deja de existir (o más exactamente, su asociación con el objeto del usuario sí lo hace)? He intentado varios métodos para evitar esto y leer este artículo para entender lo que está sucediendo aquí (http://yehudakatz.com/2009/11/15/metaprogramming-in-ruby-its-all-about-the-self/) sin éxito. –
Oh, mi mal. Básicamente, el yo en el nuevo contexto es la clase. Es similar a hacer una evaluación de clase. Hice algo así como un experimento en un proyecto personal. La parte superior de este archivo debería ayudar: https://github.com/Hitonagashi/UndergroundFootball/blob/master/app/models/player.rb –
No estoy seguro de entender: creo que estás hablando sobre el método de inicialización en tu código, donde estás agregando todas las habilidades posibles como métodos de clase dinámicamente. No veo cómo eso se aplica a mi problema, ya que no puedo agregar un objeto asociado a la clase. ¿Hay alguna forma de acceder a las relaciones de la instancia para codificar dentro del bloque de clases? –