使用activerecord从对象到表

时间:2020-03-06 14:55:55  来源:igfitidea点击:

我从外部库中获取了一些对象,并且需要将这些对象存储在数据库中。有没有一种方法可以从对象创建表和关系,或者我必须深入研究它们并手动创建迁移和模型?

谢谢!
罗伯托

解决方案

尝试查看一些ORM解决方案。或者存储为XML。

即使我们可以那样动态地动态创建表(并不是说可以)。我不想那样做。那里有很多潜在的错误。

我将手动创建迁移,并预先创建表和字段,并根据需要用行填充它们。

我有这种确切的情况。我必须读取应用程序外部的数据,并且性能影响如此之大,以至于我将其存储在本地。我提供了一个解决方案,随着时间的推移,我已经开发了一个模式并手动开发了可用于数据的迁移,并允许我将数据持久化到表中。我已经开发了一种适用于我的数据的缓存方案,并且性能得到了显着提高。

话虽这么说,我都是手工做的,我并不后悔。我可以确信我的数据库是稳定的,而且不会立即重新创建数据库表。因此,我不必担心应用程序的稳定性。

根据我们要处理的对象的不同,可以通过序列化对象将对象直接存储到数据库中。

注意:这是一个可怕的hack,我们将在未来的几年中解决这些bug,但是这很简单:

这依赖于Rails ActiveSupport,并且ActiveRecord已经被加载

假设我们从第三方库中获得了一个随机对象,该库具有2个实例变量,则该类的类可能如下所示:

class Animal
    attr_accessor :name, :number_of_legs
end
a = SomeThirdPartyLibrary.get_animal

我们可以使用反射来确定它的名称和列:

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

然后,我们可以使用ActiveRecord迁移来创建表,如下所示:

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

然后,我们最终可以声明一个activerecord类,该类将与刚刚创建的表对接。

# 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"

快点!

现在我们可以执行以下操作:

a = GeneratedClasses::Animal.new
a.update_attributes whatever
a.save

PS:不要这样做!

除了令人生畏之外,如果rails应用程序重新启动,它将丢失所有关于Generated Classes的概念,因此我们还需要设计一些持久化这些机制的机制。