FactoryGirl HABTM transactional_fixtures产生MissingAttributeError

时间:2015-03-20 14:46:53

标签: ruby-on-rails rspec transactions has-and-belongs-to-many

当系统尝试回滚数据时,我收到了rspec和HABTM关系的错误。

这是我的rspec配置:

RSpec.configure do |config|
  config.use_transactional_fixtures = true
  config.infer_spec_type_from_file_location!
end

非常虚拟的HABTM关系:

# == Schema Information
# Table name: permission
#  id            :integer          not null, primary key
#  name          :string
#  subject_class :string
#  action        :string
#  description   :text
class Permission < ActiveRecord::Base
  has_and_belongs_to_many :admin_roles
end

# == Schema Information
# Table name: admin_role_permission
#  permission_id :integer
#  admin_role_id :integer
class AdminRolePermission < ActiveRecord::Base
  belongs_to :admin_role
  belongs_to :permission
end

# == Schema Information
# Table name: admin_role
#  id         :integer          not null, primary key
#  title      :string
class AdminRole < ActiveRecord::Base
  has_and_belongs_to_many :permissions
end

我创建了基本的FactoryGirl文件,并进行了以下测试:

RSpec.describe "Check that factories are removed after each test" do

  it 'minimal test' do
    admin_role  = FactoryGirl.create(:admin_role, title: 'admin_role')
    permission  = FactoryGirl.create(:permission, name: 'test')
    FactoryGirl.create(:admin_role_permission, permission: permission, admin_role: admin_role)
    expect(AdminRole.count).to eq(1)
  end
end

这会产生这个错误:

F

Failures:

  1) Check that factories are removed after each test minimal test
     Failure/Error: Unable to find matching line from backtrace
     ActiveModel::MissingAttributeError:
       can't write unknown attribute ``
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/attribute.rb:124:in `with_value_from_database'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/attribute_set.rb:39:in `write_from_user'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/attribute_methods/write.rb:74:in `write_attribute_with_type_cast'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/attribute_methods/write.rb:56:in `write_attribute'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/attribute_methods/dirty.rb:92:in `write_attribute'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/transactions.rb:393:in `restore_transaction_record_state'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/transactions.rb:324:in `rolledback!'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/transaction.rb:73:in `rollback_records'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/transaction.rb:151:in `rollback'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/transaction.rb:183:in `rollback_transaction'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/database_statements.rb:221:in `rollback_transaction'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/fixtures.rb:961:in `block in teardown_fixtures'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/fixtures.rb:960:in `each'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/fixtures.rb:960:in `teardown_fixtures'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/fixtures.rb:830:in `after_teardown'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-rails-3.2.1/lib/rspec/rails/adapters.rb:114:in `block (2 levels) in <module:MinitestLifecycleAdapter>'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/example.rb:333:in `instance_exec'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/example.rb:333:in `instance_exec'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/hooks.rb:387:in `execute_with'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/hooks.rb:616:in `block (2 levels) in run_around_example_hooks_for'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/example.rb:247:in `call'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/example.rb:247:in `call'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/hooks.rb:617:in `run_around_example_hooks_for'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/hooks.rb:474:in `run'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/example.rb:343:in `with_around_example_hooks'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/example.rb:385:in `with_around_and_singleton_context_hooks'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/example.rb:174:in `run'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/example_group.rb:548:in `block in run_examples'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/example_group.rb:544:in `map'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/example_group.rb:544:in `run_examples'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/example_group.rb:512:in `run'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/runner.rb:110:in `block (3 levels) in run_specs'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/runner.rb:110:in `map'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/runner.rb:110:in `block (2 levels) in run_specs'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/configuration.rb:1526:in `with_suite_hooks'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/runner.rb:109:in `block in run_specs'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/reporter.rb:62:in `report'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/runner.rb:108:in `run_specs'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/runner.rb:86:in `run'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/runner.rb:70:in `run'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/runner.rb:38:in `invoke'
     # /Users/sylvestre/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/exe/rspec:4:in `<top (required)>'
     # /Users/sylvestre/.rbenv/versions/2.2.1/bin/rspec:23:in `load'
     # /Users/sylvestre/.rbenv/versions/2.2.1/bin/rspec:23:in `<main>'

如果我将use_transaction_fixtures = false。它的工作(但它坚持创建的工厂)

如何使用transactional_fixtures创建以前的代码?

1 个答案:

答案 0 :(得分:1)

我不确定这是你问题的原因,可能是。

当您使用habtm时,您应该拥有关联本身的模型。您的联接表也应该没有主键(id)字段。

您获得的错误可能与您拥有中间模型以及您的联接表中可能有主键的事实有关。

两种选择

您拥有的选项是:

  1. 通过删除AdminRolePermission模型和迁移以及为admin_roles_permissions表格创建新迁移(注意其中的复数形式)和as detailed in the docs for habtm来确保您拥有{{}来修复该问题1}}在那里,或者......
  2. 保留所有内容并使用id: false代替has_many :through,这确实会增加对象创建的负担(因为您需要实际创建连接表模型)。
  3. 手指交叉

    您的应用程序无论如何都无法正常工作,因此您无论如何都必须执行上述选项之一,但希望修复此问题还可以解决您的测试问题。