在Ruby on Rails中在运行时构建表
如果rails希望从模型名称推断表名,我将如何在运行时创建多个使用相同模型的数据库表? 我希望能够基于模型创建新对象,然后创建一个具有该对象将引用的唯一名称的新表。 有没有人可以分享任何示例或建议来帮助我找到解决方案?
这听起来像是一个架构问题 – 为什么你会有相同模型的克隆而不是将它们全部存储在同一个表中?
在关系数据库模型中,关系是定义行或元组的关系,这意味着它是关于键的属性集。 任何其他类似的属性集属于同一关系(表)。
不确定为什么你想要这样做,但它有可能:
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
替换为您希望运行时模型的模型。
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
(请参阅此处 define
的方法的文档。)(我在rubyforums上看到了这个答案。这是主题 。)
在寻找类似问题的解决方案时发现这篇文章:我需要将用户生成的报告数据(数据网格)存储在数据库中以进行进一步编辑/导出/等。 我决定在DB中为每个报告创建一个新表并对其进行ORM包装。 Nathan的回答除了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中很难做到的原因是你真的不需要这样做。 我希望有一个更简单的替代架构。
- Mysql ::错误:指定的密钥太长; 最大密钥长度为767字节:CREATE INDEX
- Rails:每个http请求都会创建一个新的连接池吗?
- 在rails上创建新的应用程序ruby
- 为什么rails将TEXT列固定为65535个字符?
- Rails选择随机记录
- 如何将mysql数据库文件连接到rails应用程序上的本地ruby
- Rails应用程序错误 – ActiveRecord :: PendingMigrationError正在等待迁移; 运行’rake db:migrate RAILS_ENV = development’来解决此问题
- 显示用户每天在所有任务上花费的时间
- 无法安装do_mysql gem?