在我正在编写的Rails 3.2.13应用程序中,我有一个名为Business
的模型。由于这个模型变得越来越胖,我决定将其分成两部分,将与可用性相关的所有代码提取到名为Availability
的Rails问题中,存储在models/concerns/business
class Business
module Availability
extend ActiveSupport::Concern
AVAILABILITY_OPEN = 1
AVAILABILITY_CLOSED = -1
AVAILABILITY_COMPLETE = -2
...
由于Rails默认情况下未启用此问题,因此我在config/application.rb
中添加以下行以自动加载它们:
config.autoload_paths += %W(#{config.root}/app/models/concerns)
问题是,在拆分后,我的所有测试都停止了工作,返回NameError: uninitialized constant Availability
错误。我想我需要在我的测试中以某种方式要求这种关注,但我还没有设法做到这一点,而且我也不明白为什么即使在没有使用它的测试中也需要这个问题。
以下是运行测试后返回的堆栈跟踪:
NameError: uninitialized constant Availability
(erb):9:in `<main>'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/erb.rb:849:in `eval'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/erb.rb:849:in `result'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures/file.rb:51:in `render'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures/file.rb:43:in `rows'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures/file.rb:29:in `each'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:670:in `block (2 levels) in read_fixture_files'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures/file.rb:20:in `open'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:669:in `block in read_fixture_files'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:668:in `each'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:668:in `read_fixture_files'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:548:in `initialize'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:482:in `new'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:482:in `block (2 levels) in create_fixtures'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:479:in `map'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:479:in `block in create_fixtures'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:232:in `disable_referential_integrity'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:476:in `create_fixtures'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:895:in `load_fixtures'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:849:in `setup_fixtures'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:407:in `_run__871072887135343583__setup__3260066542044458782__callbacks'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:405:in `__run_callback'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:385:in `_run_setup_callbacks'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:81:in `run_callbacks'
/home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/testing/setup_and_teardown.rb:35:in `run'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:919:in `block in _run_suite'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:912:in `map'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:912:in `_run_suite'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:657:in `block in _run_suites'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:655:in `each'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:655:in `_run_suites'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:867:in `_run_anything'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1060:in `run_tests'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1047:in `block in _run'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1046:in `each'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1046:in `_run'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1035:in `run'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:21:in `run'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:774:in `run'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:366:in `block (2 levels) in autorun'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:27:in `run_once'
/home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:365:in `block in autorun'
更新
这是课程Business
的摘录,其中包含Availability
关注点:
class Business < ActiveRecord::Base
include Availability
include EmailVirtualAttribute
include TelephoneVirtualAttribute
belongs_to :place
has_many :businesses_users
has_many :users, :through => :businesses_users, :uniq => true
has_many :customers, :inverse_of => :business, :dependent => :destroy
has_many :emails, :as => :contactable, :class_name => 'Email'
has_many :telephones, :as => :contactable, :class_name => 'Telephone'
...
开发/测试配置是标准配置,没有进行任何更改
test.rb
Rendezvous::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Configure static asset server for tests with Cache-Control for performance
config.serve_static_assets = true
config.static_cache_control = "public, max-age=3600"
# Log error messages when you accidentally call methods on nil
config.whiny_nils = true
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Raise exceptions instead of rendering exception templates
config.action_dispatch.show_exceptions = false
# Disable request forgery protection in test environment
config.action_controller.allow_forgery_protection = false
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
# Raise exception on mass assignment protection for Active Record models
config.active_record.mass_assignment_sanitizer = :strict
# Print deprecation notices to the stderr
config.active_support.deprecation = :stderr
end
development.rb
Rendezvous::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
# Print deprecation notices to the Rails logger
config.active_support.deprecation = :log
# Only use best-standards-support built into browsers
config.action_dispatch.best_standards_support = :builtin
# Raise exception on mass assignment protection for Active Record models
config.active_record.mass_assignment_sanitizer = :strict
# Log the query plan for queries taking more than this (works
# with SQLite, MySQL, and PostgreSQL)
config.active_record.auto_explain_threshold_in_seconds = 0.5
# Do not compress assets
config.assets.compress = false
# Expands the lines which load the assets
config.assets.debug = true
end
更新2
执行测试时发生的错误似乎是由灯具引起的。如果我在fixtures :all
上评论test_helper.rb
加载并创建一个只是断言为true的简单测试,则此测试会通过,但是在加载灯具时不会。
答案 0 :(得分:3)
最后,我找到了所有测试都因错误而失败的原因。我使用Availability
引用了Availabiliy::
关注中声明的常量,而不是使用Business::
。此外,我的测试与当前代码不同步,这使得查找错误比应该更加困难。用Availability
替换Business
的所有引用解决了这个问题。这里的教训是:始终保持应用程序和测试代码同步。
感谢Lichtamberg的一切支持。
答案 1 :(得分:1)
尝试使用特定的型号名称..例如User :: Confirmation
# -*- encoding : utf-8 -*-
require 'active_support/concern'
module Business::Availability
extend ActiveSupport::Concern
而且:
config.autoload_paths += Rails.root.join("app", "models", "concerns")
答案 2 :(得分:0)
我有点孤立问题的根源,即固定装置。我在fixtures :all
中使用test_helper.rb
方法。将其更改为只运行customers.yml
夹具,我可以运行customer_test.rb
而没有错误。我还不知道有什么令人讨厌的装置(我认为businesses.yml
可能是相关的,但我没有检查过它,以及为什么会导致这个问题。