创建表和Ruby on Rails 3 中的动态(动态)模型

发布于 2024-10-31 10:58:04 字数 593 浏览 1 评论 0原文

请耐心听我讲这一点。

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

旧的(现已不复存在的系统)使用 PHP 进行处理这很好,虽然相当混乱,有大量原始 SQL 来创建表,并且框架支持魔术模型(如果表存在,则模型文件中没有定义类的对象也存在)

新版本正在 RoR3 中编写,我还没有找到办法做到这一点。我已经设法通过调用模型内的迁移工具来整理表创建(我知道不是很 Rails-y,但必须...),但是一旦创建新表,我就找不到链接到新表的方法写入数据、建立关系或其他任何内容。

我希望的是,

a)这里有人有比动态创建表和模型更好的方法(这里警告,这些文件可以包含 100'000 条记录和不同的字段,因此单个表选项效果不太好),即针对此问题的更好的数据库设计。

或者

b)可以告诉我如何解决模型问题。

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

抱歉文字墙,期待任何建议

提前致谢

Bear with me on this one.

In an app I'm working on users are able to upload CSV files into the system, with any headers they like and any columns in the data. The CSV is then used to generate a table in the database and the data written to it, it can then be accessed through the system for various uses, searches, sorts updates etc.

The old (and now defunct system) was in PHP and handled this fine, although quite messily with lots of raw sql to create the tables and the framework supported magic-models (if the table existed so did the object without a class being defined in a model file)

The new version is being written in RoR3, and I am yet to figure out a way to do this. I've managed to sort out the table creation by calling migration tools inside a model (not very Rails-y I know, but needs must...), but I cannot find a way to link to the new table once it's created to write in the data, build relationships or anything else.

What I'm hoping for is either,

a) someone on here has a better way of doing this than creating tables and models on the fly (a warning here, these files can contain 100'000's of records and different fields so a single table option doesn't work so well) i.e a better database design for this issue.

or

b) can tell me how to sort out the model issue.

I've looked at Dr Nic's Magic Model gem for RoR but it doesn't seem to work in RoR3 unless I'm doing something wrong

Sorry for the wall of text, look forward to any suggestions

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

合约呢 2024-11-07 10:58:04

好吧,我想出了一个解决方案,但如果很好那就是另一回事了。

基本上,您可以通过 Rail ActiveRecord 执行 SQL 来动态创建表。
接下来使用模型并更改其名称(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

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

我想这并不是真正的最佳实践,但如果你需要这个。我想这可能会起作用!

OK, i got a solution i think, but if is nice thats different thing.

Basically you create a table on the fly by executing SQL thru Rail ActiveRecord.
Next use a Model and change its name (Model.table_name).

Something like this:

    // 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)

Then with a model you can change the table name on the fly, like:

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

Ok, one of your problems is the model logic & associations. You are kind of limited, but maybe you can workaround that.

Not really best practices i guess, but if you need this. I think it might work!

瑕疵 2024-11-07 10:58:04

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

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

I have implemented app which is used to upload a csv file and convert the file into a active record model. you can checkout this repository.

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

here is a small idea about how it was achieved:

   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

There are also some glitches with this it is difficult to add association and also validations

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文