在应用程序Ruby-Datamapper中指定表名

时间:2012-08-28 00:44:49

标签: ruby ruby-datamapper

我想使用Datamapper动态创建和查询表。

虽然Datamapper允许您使用遗留表和模式,但这样设置使用的表名仅在初始化期间,而不是在应用程序中。

是否有一种简单的方法可以告诉Datamapper在应用程序中迁移/升级具有指定表名的Model,然后告诉它查询该表?

2 个答案:

答案 0 :(得分:1)

这应该不是问题。

可以创建所有Ruby类,并在运行时重新定义。甚至初始化也是在运行时。在执行其他代码之前,初始化恰好首先执行。

这就是为什么猴子补丁很容易工作的原因。它只是在初始化时的附加代码,只是重新定义类以添加额外的方法,变量等。

没有Ruby代码是“特殊的”,因为它只在编译时运行。 Ruby是一种解释语言。


要动态创建课程,请参阅Dynamically creating class in Ruby

假设您不需要从字符串数组动态创建类,可以使用define_method定义其他方法,或者在运行时调用Datamapper方法来添加属性。

在类中定义新方法:

Post.send :define_method, :new_method_name do
end

使用Datamapper属性定义新属性:

class Post
  include DataMapper::Resource
  property :title, String # the static way
end

Post.send :property, :title, String # add property the dynamic way (at run-time)

请注意,如果重新启动服务器,则在运行时定义的任何表或属性都将不可用,除非重新执行动态生成这些的代码。


要在运行时更新表,您只需执行与正常相同的操作,即调用:

DataMapper.auto_upgrade!

要仅升级单个表,您还可以执行以下操作:

Post.auto_upgrade!

第二次警告:如果您有多个流程,则需要在每个流程中运行动态代码,否则其他表格“模型”和“属性”将不可用。

如果您有多个工作进程,这是一个问题,如生产中可能发生的那样(例如,有多个Unicorn工作人员的Nginx,或Ha_proxy背后的多个Mongrel工作人员)。

如果您有一个进程服务器,那么这不是问题。但是,如果您有多个工作进程,则必须运行动​​态代码以在EACH过程中生成这些额外的类和属性,以使其可用。

这对于初始化实际上是相同的,因为每个进程都经历初始化(或者如果是分叉的,则继承任何初始化)。

答案 1 :(得分:0)

不改变任何内容的最简单方法是使用单独的数据库而不是表(假设任何关系也将存储在单独的数据库中)并打开与块中其他存储库的连接。

DataMapper.setup(:external, "adapter://username:password@hostname/dbname")
DataMapper.repository(:external) do...end