Восстановить тестовые файлы фикстуры в Rails
Как мне восстановить все файлы фиксации YML? Я случайно удалил их.
2 ответа
@Брайан,
Я использую следующий скрипт для генерации светильников из данного sql
Это в моей директории lib/task как грабли
namespace :fixture_generator do
desc "generate fixtures for a given sql query from the current development database"
task :fixture_generator, [:sql, :file_name] => :environment do |t, args|
args.with_defaults(:sql => nil, :file_name => nil)
i = "000"
p "creating fixture - #{args.file_name}"
File.open("#{Rails.root}/test/fixtures/#{args.file_name}.yml", 'a+') do |file|
data = ActiveRecord::Base.connection.select_all(args.sql)
file.write data.inject({}) { |hash, record|
number = i.succ!
hash["#{args.file_name}_#{number}"] = record
hash
}.to_yaml
end
end
end
Использование, скажем, я хочу создать таблицу для пользователей таблицы
rake fixture_generator:fixture_generator["select * from users","users"]
А также, если вы запустите другой запрос с тем же именем файла фикстуры, он добавится к существующему
НТН
Когда я использую Nested Set в нашем приложении (скажем, здесь модель MyTree), перед использованием требуется расчет столбцов lft/rgt (конечно, в том числе и во время тестирования). Чтобы установить сбор lft/rgt для всех записей в приспособлении MyTree, можно использовать несколько подходов:
- а) вручную запишите рассчитанные значения lft/rgt для всех записей my_trees.yml.
- б) выполнить MyTree.rebuild! в блоке для каждого необходимого теста.
- в) сгенерировать расчетный файл прибора со значениями lft/rgt.
а) вышеописанное — довольно утомительная задача для человека. б) потребляет ресурсы ЦП во время теста для каждогоsetup
. Я думаю, что c) — лучший подход, поэтому я публикую свой код здесь.
Код @sameera207 не может быть применен в нашем случае, поскольку я использую ссылки на метки для ввода приборов, поэтому я пишу следующую «задачу по рейку», которая генерируется изtest/fixtures.src/my_trees.yml
:
Например, модель данных:
class MyTree < ApplicationRecord
acts_as_nested_set
...
end
и генерирующая задача:
namespace :my_app do
desc 'rebuild from test/fixtures.src/my_trees.yml to test/fixtures/my_trees.yml'
task rebuild_my_trees_fixture: :environment do
require 'active_record/fixtures'
if !Rails.env.test?
puts('not test env')
next
end
id_to_entry = {} # ActiveRecord::FixtureSet#idnetity -> entry name
for key, val in YAML.load(ERB.new(File.read('test/fixtures.src/my_trees.yml'), 0, '-').result) do
id_to_entry[ActiveRecord::FixtureSet.identify(key)] = key
end
MyTree.transaction do
MyTree.delete_all
# load source to DB
::ActiveRecord::FixtureSet.create_fixtures('test/fixtures.src', 'my_trees')
MyTree.rebuild!(false)
File.open(Rails.root + 'test/fixtures/my_trees.yml', 'w') do |f|
# write header
f.write <<~EOS
# ===================================================================
# Do not modify this file manually!!
# This file is automatically generated.
# ===================================================================
EOS
hash = {}
for rec in MyTree.all do
key = id_to_entry[rec.id]
if key.nil?
STDERR.printf("ERROR: entry not found for id(%d)\n", rec.id)
else
hash[id_to_entry[rec.id]] = rec.attributes.except('id')
end
end
f.write(hash.to_yaml)
end
# cache should be cleaned here. Otherwise this working my_trees table
# remains at the 'rake test' later.
::ActiveRecord::FixtureSet.reset_cache
raise ActiveRecord::Rollback
end
end
end
# invoke above task before 'rake test'
task :'test' => 'my_app:rebuild_my_trees_fixture'
Ключевым моментом являетсяMyTree.rebuild!
в приведенном выше коде, который вычисляет все значения lft/rgt для всех записей. Все остальные фрагменты кода выше — это всего лишь подготовка и генерация.
ДЕЛАТЬ
У меня не было времени написать эту задачу, которая будет вызываться триггером зависимости файлов междуfixtures.src/my_trees.yml
иtest/fixtures/my_trees.yml
.