如何将.yml文件中的数据加载到数据库?

时间:2010-06-21 06:59:15

标签: ruby-on-rails fixtures

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

'questions.yml'从表中有一些recodes dump。

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

但没有插入数据库

3 个答案:

答案 0 :(得分:7)

将日期从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")

答案 1 :(得分:1)

这会将灯具加载到当前的RAILS_ENV中,默认情况下是RAILS_ENV。

$ rake db:fixtures:load

答案 2 :(得分:0)

感谢@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