Как загрузить данные из файла .yml в базу данных? - PullRequest
4 голосов
/ 21 июня 2010

Есть таблица 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

Но я не знаю, как их вставить.


Edit:

Я пробовал:

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

и

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

Но в базу данных ничего не вставлено

Ответы [ 3 ]

7 голосов
/ 21 июня 2010

Попробуйте после загрузки даты из файла 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. Просто напишите приведенный выше код в скрипт, отвечающий за импорт.

UPDATE:

Вы можете использовать следующую функцию:

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

источник

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 голос
/ 13 октября 2015

Это загружает приборы в текущий RAILS_ENV, который по умолчанию является развитием.

$ rake db:fixtures:load
0 голосов
/ 04 февраля 2014

Получил работу благодаря ответу @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
...