De los objetos a las tablas usando activerecord.
-
03-07-2019 - |
Pregunta
Obtengo algunos objetos de una biblioteca externa y necesito almacenar esos objetos en una base de datos. ¿Hay alguna forma de crear las tablas y relaciones a partir de los objetos, o tengo que profundizar en ellas y crear migraciones y modelos a mano?
Gracias! Roberto
Solución
Incluso si pudieras crear dinámicamente tablas sobre la marcha así (sin decir que puedes). No querría hacer eso. Hay mucho potencial de error allí.
Yo crearía las migraciones a mano y tendría las tablas y los campos creados previamente y los completaría con filas según sea necesario.
Otros consejos
Nota: este es un hack TERRIBLE y estarás solucionando los errores durante los próximos años, pero sin embargo es bastante fácil:
Esto se basa en los rieles ActiveSupport, y ActiveRecord ya se está cargando
Supongamos que obtiene un objeto aleatorio de una biblioteca de terceros que tiene 2 variables de instancia; su clase podría tener este aspecto:
class Animal
attr_accessor :name, :number_of_legs
end
a = SomeThirdPartyLibrary.get_animal
Puedes usar la reflexión para averiguar su nombre y columnas:
table_name = a.class.to_s.tableize
column_names = a.instance_variables.map{ |n| n[1..-1] } # remove the @
column_types = a.instance_variables.map{ |n| a.instance_variable_get(n).class
}.map{ |c| sql_type_for_class(c) } # go write sql_type_for_class please
Luego puedes usar las migraciones de ActiveRecord para crear tu tabla, de esta manera:
ActiveRecord::Migration.class_eval do
create_table table_name do |t|
column_names.zip(column_types).each do |colname, coltype|
t.column colname, coltype
end
end
end
Luego, finalmente puede declarar una clase de registro de activación que luego se interconectará con la tabla recién creada.
# Note we declare a module so the new classes don't conflict with the existing ones
module GeneratedClasses; end
eval "class GeneratedClasses::#{a.class} < ActiveRecord::Base; end"
¡Presto!
Ahora puedes hacer esto:
a = GeneratedClasses::Animal.new
a.update_attributes whatever
a.save
PS: ¡No hagas esto!
Además de ser horrible, si tu aplicación Rails se reinicia, perderá todo el concepto de las Clases Generadas, por lo que también tendrás que idear algún mecanismo para persistir en ellas.
Tengo esta situación exacta. Tengo que leer datos externos a la aplicación y el impacto de rendimiento es tan grande que los almaceno localmente. He ido con una solución en la que, con el tiempo, he desarrollado un esquema y migraciones a mano, que funcionan con los datos y me permiten conservar los datos en las tablas. He desarrollado un esquema de almacenamiento en caché que funciona para mis datos y el rendimiento ha aumentado significativamente.
Todo lo que hay que decir, lo hice todo a mano y no me arrepiento. Puedo confiar en que mi base de datos es estable y que no estoy recreando las tablas db sobre la marcha. Por eso, no me preocupa la estabilidad de mi aplicación.
Dependiendo de lo que intente hacer con los objetos, puede almacenar objetos directamente en la base de datos por serializarlos .
Intente ver algunas soluciones ORM. O almacenar como XML.