【发布时间】:2009-01-29 04:26:32
【问题描述】:
鉴于 rails 想要从模型名称推断表名称,我将如何在运行时创建多个使用相同模型的数据库表?我希望能够基于模型创建一个新对象,然后创建一个具有该对象将引用的唯一名称的新表。有没有人可以分享任何示例或建议来帮助我找到解决方案?
【问题讨论】:
标签: mysql ruby-on-rails ruby database
鉴于 rails 想要从模型名称推断表名称,我将如何在运行时创建多个使用相同模型的数据库表?我希望能够基于模型创建一个新对象,然后创建一个具有该对象将引用的唯一名称的新表。有没有人可以分享任何示例或建议来帮助我找到解决方案?
【问题讨论】:
标签: mysql ruby-on-rails ruby database
这听起来像是一个架构问题 - 为什么会有相同模型的克隆而不是将它们全部存储在同一个表中?
在关系数据库模型中,关系定义了行或元组,这意味着它是关于键的属性集。任何其他类似的属性集都属于同一关系(表)。
【讨论】:
def self.create_table
ActiveRecord::Schema.define do
create_table :my_table_name do |t|
#(define your columns just as you would in a migration file)
t.string :my_string
end
end
end
(有关方法definehere,请参阅文档。)
(我在 rubyforums 看到了这个答案。这里是 the thread。)
【讨论】:
不确定您到底为什么要这样做,但有可能:
runtime_table_name = "random"
ActiveRecord::Migration.create_table(runtime_table_name) do
# Table definition goes here
end
eval <<-EOS
class #{runtime_table_name.classify} < YourBaseModel
set_table_name #{runtime_table_name.inspect}
end
EOS
runtime_model = runtime_table_name.classify.constantize
runtime_model.find(:all)
您只需将YourBaseModel 替换为您希望运行时模型的任何模型即可。
【讨论】:
在寻找类似问题的解决方案时发现了这篇文章:我需要将用户生成的报告数据(数据网格)存储在数据库中,以便进一步编辑/导出/等。我决定在数据库中为每个报告创建一个新表并对其进行 ORM 包装。除了 eval 部分之外,内森的回答有所帮助,我认为这与当前范围有关。我试图在实例方法中定义一个新类(after_save 钩子),所以当我后来从另一个方法引用新常量时,我得到了一个NameError。将binding 显式传递给eval 也无济于事,原因不明(绑定错误?),所以我这样做了:
klass = Class.new(ActiveRecord::Base) do
# class body goes here
end
Object.const_set(class_name, klass)
【讨论】:
我猜,创建表是可能的。使用 ActiveRecord::Base.connection.execute 执行类似“CREATE TABLE newtab AS SELECT * FROM oldtab WHERE 0=1”。
然后您可能会以某种方式执行 set_table_name 以将您的模型指向创建的表。
获得更多关于您认为自己有什么问题需要这种扭曲的解决方案的信息真的很有帮助。在 Rails 中很难做到的原因是你真的不需要这样做。我希望有一个更简单的替代架构。
【讨论】: