在我的应用中,我在创建主题记录时创建了一个目录。这是为了存储与主题相关的文件资产。我一直在努力避免如何使目录的存在与记录的生命周期保持同步。这是我目前的看法:
after_create :create_theme_directory
after_rollback :destroy_theme_directory, :on => :create, :if => :id
def directory
Rails.configuration.uploads_root.join('themes', id.to_s)
end
private
def create_theme_directory
FileUtils.mkdir_p directory
end
def destroy_theme_directory
FileUtils.remove_dir directory, :force => true
end
除了Rspec在测试后回滚主题记录时似乎没有触发删除目录外,它运行良好。
这种事情有最好的做法吗?我们的想法是永远不要留下没有相关记录的迷路目录。
答案 0 :(得分:1)
我感兴趣的非常有趣的问题,因为我目前正在开发一个上传和转换文件的应用程序。
根本不是RSpec的专家,但我认为它非常依赖于数据库,如果它与数据库无关(如创建文件夹/更新),则由用户自行清理图像/启动外部接口)。
找到关于如何使用after(:all)进行清理with RSepc and carrierwave testing的示例 - 与我的初始类似。
另一种选择是更务实,在测试方面可能更有限。 为目标结构提供备份文件,并在测试完成后将其恢复。
如果有人有更好的方法,我确实感兴趣。
希望这有帮助! 欧根
答案 1 :(得分:1)
如果通过ActiveRecord创建,销毁或更新记录,则只会调用已定义的after_rollback
回调。当RSpec重置时,它不会通过ActiveRecord,因此它不会触发任何事务回调(after_rollback和after_commit)。
如果目录仍然存在,您可以添加另一个销毁该目录的回调:
after_commit :destroy_theme_directory, :on => :destroy
def destroy_theme_directory
if File.directory?(directory)
FileUtils.remove_dir directory, :force => true
end
end
然后在功能规范中触发创建和销毁操作:
scenario 'create and destroy' do
visit new_directory_path
#fill_in fields
click_button "Create"
expect(page).to have_content "created"
visit users_path
click_link "Delete" #assuming only directory object exists and you have a delete link in your directory index page
end
通过这种方式,您可以在规范中触发创建和销毁操作,因此您无需进行任何清理。
另一个选项是手动删除测试其创建的规范中的目录。
#assuming you have model spec for testing that directory is created
it 'creates corresponding directory'
directory.create
expect(File.directory?(directory)).to eq true
# the line below is just for cleanup. No need to do it in an after_all block if it only needs to be done for a few specs
FileUtils.remove_dir directory, :force => true
end
希望有所帮助。