2011-04-09 107 views
8

在这个问题上忍受着我。在Ruby on Rails中动态地创建表格和模型3

在我正在处理的应用程序中,用户可以将CSV文件上传到系统中,并可以使用任何他们喜欢的标题和数据中的任何列。然后用CSV在数据库中生成一个表格并写入数据,然后可以通过系统访问它,以便进行各种用途,搜索,分类更新等。

旧的(现在已经不存在的系统)是在PHP中并且处理得很好,尽管很多原始sql用于创建表和框架支持的魔法模型(如果表存在,那么没有在模型文件中定义类的对象也是如此)0123新版本正在RoR3中编写,我还没有想出一个办法来做到这一点。我已经设法通过调用模型内的迁移工具来清理表的创建(不是非常Rails-y我知道,但需要......),但是我无法找到一种方法来创建新表写入数据,建立关系或其他任何东西。

是什么,我希望无论是,

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

B)能告诉我如何理清模型问题。

我已经看了尼克博士的魔法宝石型的回报率,但它似乎并没有在RoR3工作,除非我做错了

对不起,文字的墙上,期待什么建议

在此先感谢

+0

只是胡乱认为:也许尝试创建一个迁移文件,然后重新加载该文件和db:migrate。 – Zabba 2011-04-09 07:48:00

+0

@Zabba,那会达到什么样的效果?请原谅我缺乏RoR的经验,但是迁移不是仅仅创建表格而不是模型?或者你是否认为这将是创建表的“更好”方式? – fullybaked 2011-04-09 07:54:04

+0

是的,我的意思是创建表格的部分。但你也可以创建模型文件并加载它,我*假设*。目前还没有这方面的经验。 – Zabba 2011-04-09 07:56:52

回答

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) 

然后用模型,你可以更改表名称上的苍蝇,像:

MyModel.table_name = "my_table" 
records = MyModel.all 

好了,你的问题之一是模型逻辑&协会。你是有限的,但也许你可以解决这个问题。

我猜不是最好的实践,但如果你需要这个。我认为它可能工作!

5

我已经实现了用于上传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 

也有一些毛刺这个就很难添加关联,也验证