【问题标题】:How to load the data from a .yml file to database?如何将数据从 .yml 文件加载到数据库?
【发布时间】:2010-06-21 06:59:15
【问题描述】:

有一个表questions,和一个数据文件questions.yml。假设没有“问题”模型。

'questions.yml' 有一些从表中转储的重新编码。

---
questions_001:
  title: ttt1
  content: ccc1
questions_002:
  title: ttt2
  content: ccc2

我想从 yml 文件加载数据,将它们插入数据库。但是我不能使用rake db:fixtures:load,因为它会将内容视为'erb'模板,这不是我想要的

所以我想写另一个 rake 任务,手动加载数据。

我可以通过以下方式阅读记录:

File.open("#{RAILS_ROOT}/db/fixtures/#{table_name}.yml", 'r') do |file|
   YAML::load(file).each do |record|
      # how to insert the record??
   end
end

但我不知道如何插入它们。


编辑:

我试过了:

Class.new(ActiveRecord::Base).create(record)

class Dummy < ActiveRecord::Base {}
Dummy.create(rcord)

但没有插入数据库

【问题讨论】:

    标签: ruby-on-rails fixtures


    【解决方案1】:

    将yml文件中的日期加载到records后试试这个:

    class Question < ActiveRecord::Base
      # Question model just to import the yml file
    end
    records.each { |record| Question.create(record) }
    

    您可以简单地创建一个仅用于导入的模型。您无需创建app/models/question.rb。只需在负责导入的脚本中编写上述代码即可。

    更新:

    您可以使用以下功能:

    def create_class(class_name, superclass, &block)
      klass = Class.new superclass, &block
      Object.const_set class_name, klass
    end
    

    source

    File.open("#{RAILS_ROOT}/db/fixtures/#{table_name}.yml", 'r') do |file|
      YAML::load(file).each do |record|
        model_name = table_name.singularize.camelize
        create_class(model_name, ActiveRecod::Base) do
          set_table_name table_name.to_sym
        end
        Kernel.const_get(model_name).create(record)
      end
    end
    

    要直接使用连接,您可以使用以下内容:

    ActiveRecord::Base.connection.execute("YOUR SQL CODE")
    

    【讨论】:

    • @Jens Fahnenbruck,谢谢,但我认为没有模型“问题”,只有表格和 yml 文件。
    • 我有这个限制,因为有些表没有对应的Models,比如'questions_tags'
    • @Jens,谢谢,但很抱歉,我仍然需要你的帮助。实际上,不仅有“问题”表,还有“标签/问题标签/答案/用户”等其他表,我无法为它们显式定义模型。还有其他常用方法吗?比如只给一个connection、table_name和一个hash(record),然后插入到数据库中?
    • 为所有这些表创建虚拟模型。它应该工作
    • 是的,模型名称应该是表名的单数和大写版本。我已经更新了我的答案,现在它应该可以工作了
    【解决方案2】:

    这会将固定装置加载到当前的 RAILS_ENV 中,默认情况下,它是开发状态。

    $ rake db:fixtures:load
    

    【讨论】:

      【解决方案3】:

      感谢@jigfox 的回答,它可以正常工作。现在必须对 Rails 4 的完整实现进行一些修改。

      table_names = Dir.glob(Rails.root + 'app/models/**.rb').map { |s| Pathname.new(s).basename.to_s.gsub(/\.rb$/,'') }    
      
      table_names.each do |table_name|
        table_name = table_name.pluralize
        path = "#{Rails.root}/db/fixtures/#{table_name}.yml"
        if File.exists?(path)
          File.open(path, 'r') do |file|
            y = YAML::load(file)
            if !y.nil? and y
              y.each do |record|
                model_name = table_name.singularize.camelize
                rec = record[1] 
                rec.tap { |hs| hs.delete("id") }
                Kernel.const_get(model_name).create(rec)
              end
            end
          end
        end
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-02
        相关资源
        最近更新 更多