Spork.prefork загружает приложение/модели/*
Я не могу понять, как получить spork, чтобы не загружать все мои модели приложений. Тестирование изменений в моих моделях сильно замедляется, поскольку я не могу использовать spork для помощи. Это то, что я получаю, когда я отлаживаю загрузку справки:
- Spork Diagnosis -
-- Summary --
app/models/account.rb
app/models/admin.rb
app/models/affiliate.rb
app/models/app.rb
app/models/application_server.rb
app/models/domain_record.rb
app/models/domain_zone.rb
app/models/event.rb
app/models/oid.rb
app/models/user.rb
config/application.rb
config/boot.rb
config/environment.rb
config/environments/test.rb
config/initializers/api_conversions.rb
config/initializers/backtrace_silencers.rb
config/initializers/compass.rb
config/initializers/devise.rb
config/initializers/hoptoad.rb
config/initializers/inflections.rb
config/initializers/mime_types.rb
config/initializers/rspec_generator.rb
config/initializers/secret_token.rb
config/initializers/session_store.rb
config/routes.rb
lib/application_server_api.rb
lib/oid_helper.rb
lib/soa_record.rb
spec/spec_helper.rb
-- Detail --
--- app/models/account.rb ---
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:239:in `block in require'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:227:in `load_dependency'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:239:in `require'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:346:in `require_or_load'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:300:in `depend_on'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:216:in `require_dependency'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/mongoid-2.0.0.rc.7/lib/rails/mongoid.rb:54:in `load_model'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/mongoid-2.0.0.rc.7/lib/rails/mongoid.rb:17:in `block (2 levels) in load_models'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/mongoid-2.0.0.rc.7/lib/rails/mongoid.rb:16:in `each'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/mongoid-2.0.0.rc.7/lib/rails/mongoid.rb:16:in `block in load_models'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/paths.rb:102:in `block in each'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/paths.rb:102:in `each'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/paths.rb:102:in `each'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/mongoid-2.0.0.rc.7/lib/rails/mongoid.rb:15:in `load_models'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/mongoid-2.0.0.rc.7/lib/mongoid/railtie.rb:88:in `block (2 levels) in '
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/callbacks.rb:419:in `_run_prepare_callbacks'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/actionpack-3.0.3/lib/action_dispatch/middleware/callbacks.rb:40:in `initialize'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/actionpack-3.0.3/lib/action_dispatch/middleware/stack.rb:33:in `new'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/actionpack-3.0.3/lib/action_dispatch/middleware/stack.rb:33:in `build'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/actionpack-3.0.3/lib/action_dispatch/middleware/stack.rb:79:in `block in build'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/actionpack-3.0.3/lib/action_dispatch/middleware/stack.rb:79:in `each'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/actionpack-3.0.3/lib/action_dispatch/middleware/stack.rb:79:in `inject'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/actionpack-3.0.3/lib/action_dispatch/middleware/stack.rb:79:in `build'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/application.rb:162:in `app'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/application/finisher.rb:35:in `block in '
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/initializable.rb:25:in `instance_exec'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/initializable.rb:25:in `run'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/initializable.rb:50:in `block in run_initializers'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/initializable.rb:49:in `each'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/initializable.rb:49:in `run_initializers'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/application.rb:134:in `initialize!'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/application.rb:77:in `method_missing'
config/environment.rb:8:in `'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:239:in `block in require'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:225:in `block in load_dependency'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:596:in `new_constants_in'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:225:in `load_dependency'
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:239:in `require'
spec/spec_helper.rb:9:in `block in '
/Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/spork-0.9.0.rc3/lib/spork.rb:23:in `prefork'
spec/spec_helper.rb:4:in `'
update: my spec_helper.rb
require 'rubygems'
require 'spork'
ENV["RAILS_ENV"] = "test"
Spork.prefork do
require File.expand_path(File.dirname(__FILE__) + '/../config/environment')
require 'rspec/rails'
end
Spork.each_run do
# Hub::Application.reload_routes!
end
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
Если я перемещаю require File.expand_path(File.dirname(__FILE__) + '/../config/environment')
из предпродажа, мои модели не предварительно загружаются, но, как вы могли ожидать, для выполнения моих тестов потребуется намного больше времени.
Любые идеи о том, как заставить spork не загружать модели в приложение Rails 3? Я пробовал использовать spork 0.8.4, master branch и в настоящее время 0.9.0.rc3. У кого-нибудь есть идеи, как я могу избежать предварительной загрузки моделей?
Ответы
Ответ 1
После многократного вращения моих колес у меня наконец есть что-то приемлемое:
Spork.prefork do
require "rails/mongoid"
Spork.trap_class_method(Rails::Mongoid, :load_models)
# The following does not work correctly with Devise routes that load the User model.
# Results in NameError unintitialized *
# :reload_routes! triggers :devise_for which loads and caches the User class.
# https://github.com/timcharper/spork/wiki/Spork.trap_method-Jujutsu
# require "rails/application"
# Spork.trap_method(Rails::Application, :reload_routes!)
require 'factory_girl_rails'
Spork.trap_class_method(Factory, :find_definitions)
require File.expand_path(File.dirname(__FILE__) + '/../config/environment')
end
Проблема была в основном из-за Rails:: Mongoid # load_models. После проверки отладочной информации о spork и обратном отображении того, как вещи загружаются, даются некоторые подсказки относительно того, что загружает модели. Эта страница немного подробнее https://github.com/timcharper/spork/wiki/Spork.trap_method-Jujutsu, но я не нахожу: reload_routes! помогая Devise заставлять пользовательский класс предварительно загружаться.
Теперь мои спецификации работают намного быстрее. Если бы я мог заставить мою модель User не кэшироваться, я был бы в блаженстве, но до тех пор я буду в основном удовлетворен.
Ответ 2
У меня есть следующая настройка как RSpec, так и Cucumber on Rails 3.1, а модели обновляются:
Установите factory_girls_rails require => false
в свой Gemfile
gem 'factory_girl_rails', :require => false
Замените блоки Spork.prefork и Spork.each_run следующим кодом.
if Spork.using_spork?
ActiveSupport::Dependencies.clear
ActiveRecord::Base.instantiate_observers
Spork.prefork do
end
Spork.each_run do
require 'factory_girl_rails'
# reload all the models
Dir["#{Rails.root}/app/models/**/*.rb"].each do |model|
load model
end
# reload routes
Rails.application.reload_routes!
end
end
Ответ 3
Следующее решение, предложенное здесь, работает для меня. Он также перезагружает модель User.
# env.rb
Spork.each_run do
require 'factory_girl_rails'
# reload all the models
Dir["#{Rails.root}/app/models/**/*.rb"].each do |model|
load model
end
end
Ответ 4
Это решение работает для меня (от http://my.rails-royce.org/2011/03/17/rspec-2-and-fixtures/)
Spork.prefork do
require 'rails/application'
Spork.trap_method(Rails::Application, :reload_routes!)
Spork.trap_method(Rails::Application::RoutesReloader, :reload!)
Spork.trap_method(Rails::Application, :eager_load!)
require File.expand_path("../../config/environment", __FILE__)
Rails.application.railties.all { |r| r.eager_load! }
require 'rspec/rails'
RSpec.configure do |config|
...
end
end
Обратите внимание, что выполнение "load model" в each_run является лишь частичным решением, это приведет к переоценке кода модели, но, например, после удаления метода модели он все равно будет существовать в памяти до тех пор, пока вы не перезапустите Spork.