在Ruby on Rails 3中动态创建表和模型

ful*_*ked 8 database-design ruby-on-rails ruby-on-rails-3

请耐心等待.

在我正在开发的应用程序中,用户可以将CSV文件上传到系统中,包括他们喜欢的任何标题以及数据中的任何列.然后使用CSV在数据库中生成一个表并将数据写入其中,然后可以通过系统访问它以进行各种用途,搜索,排序更新等.

旧的(现在已经不复存在的系统)是在PHP中并处理得很好,尽管很多原始sql创建表和框架支持魔术模型(如果表存在,所以没有在类中定义的对象)模型文件)

新版本是用RoR3编写的,我还没想办法做到这一点.我已经设法通过在模型中调用迁移工具来解决表创建问题(不是很多Rails-y我知道,但需要...),但是一旦创建到新表,我找不到链接到新表的方法写入数据,建立关系或其他任何东西.

我希望的是,

a)这里的某个人有更好的方法来做到这一点,而不是动态创建表格和模型(这里的警告,这些文件可以包含100'000的记录和不同的字段,因此单个表格选项不能很好地工作)即针对此问题的更好的数据库设计.

要么

b)可以告诉我如何理清模型问题.

我已经看过Nic博士的魔法模型宝石用于RoR但它似乎在RoR3中不起作用,除非我做错了什么

对不起文字墙,期待任何建议

提前致谢

Rog*_*ger 9

好吧,我认为我得到了一个解决方案,但如果很好,那就不一样了.

基本上,您通过执行SQL通过Rail ActiveRecord来动态创建表.接下来使用Model并更改其名称(Model.table_name).

像这样的东西:

    // SQL Create table
    sql = "CREATE TABLE my_table (id int(11) NOT NULL AUTO_INCREMENT, code varchar(3) NOT NULL)"
    ActiveRecord::Base.connection.execute(sql)
Run Code Online (Sandbox Code Playgroud)

然后使用模型,您可以动态更改表名称,如:

MyModel.table_name = "my_table"
records = MyModel.all
Run Code Online (Sandbox Code Playgroud)

好吧,你的一个问题是模型逻辑和关联.你有点受限,但也许你可以解决这个问题.

我猜不是最好的做法,但如果你需要这个.我认为它可能会奏效!


Ath*_*osh 5

我已经实现了app,用于上传csv文件并将文件转换为活动记录模型.你可以签出这个存储库.

访问https://github.com/Athul92/Salary_Sheet_Comparison/blob/master/app/models/makemodel.rb

这是一个关于如何实现的小想法:

   class Makemodel < ActiveRecord::Migration
     def self.import(file,project_name,file_name,start_row,end_row,unique,last_column)
       spreadsheet = open_spreadsheet(file)
       header = spreadsheet.row(start_row.to_i)
       i=0
       header.count.times do
         unless header[i].nil?
           header[i]= header[i].gsub(/[^0-9A-Za-z]/, '').downcase
         end
         i+=1
       end
       name = "#{project_name.downcase}"+"#{file_name.downcase}"
       create_table name.pluralize do |t|
         header.each do |head|
           t.string head
         end
       end
       model_file = File.join("app", "models", name.singularize+".rb")
       model_name = name.singularize.capitalize
       File.open(model_file, "w+") do |f|
         f << "class #{model_name} < ActiveRecord::Base\nend"
       end

       ((start_row.to_i+1)..end_row.to_i).each do |i|
         row = Hash[[header, spreadsheet.row(i)].transpose]
         #should find a logic to find the model class that is being created
         product = Object.const_get(name.capitalize).new
         product.attributes = row.to_hash
         product.save!
       end
     end

     def self.open_spreadsheet(file)
       case File.extname(file.original_filename)
         when ".csv" then Csv.new(file.path, nil, :ignore)
         when ".xls" then Roo::Excel.new(file.path)
         when ".xlsx" then Roo::Excelx.new(file.path)
         else raise "Unknown file type: #{file.original_filename}"
       end
     end
   end
Run Code Online (Sandbox Code Playgroud)

还有一些故障,很难添加关联和验证