RSpec / Capybara测试失败,模型设定器没有方法错误

时间:2014-08-04 18:57:25

标签: ruby-on-rails rspec devise capybara rspec-rails

短版

我已经在我的rails应用程序中添加了一个公司模型,该应用程序位于设计用户注册视图中,使用用户模型上的accepts_nested_attributes。当我手动运行它时,设置工作,但当我执行测试时,它失败了:

Failure/Error: click_button 'Sign up'
     NoMethodError:
       undefined method `owner_id=' for #<Company:0x007fe2411e17b8>

如何修复此错误?我不确定它告诉我的是什么。

规格/功能中的测试代码:

authentication_flows_spec.rb

it "signs me up" do
  visit new_user_registration_path
  fill_in 'user[email]', with: @new_user[:email]
  fill_in 'user[password]', with: @new_user[:password]
  fill_in 'user[password_confirmation]', with: @new_user[:password]
  fill_in 'user[company_attributes][name]', with: @new_user[:company_name]
  click_button 'Sign up'
  expect(current_path).to eq(dashboard_path)
end

长版

最近我在我的应用程序中添加了一个公司模型,它有两个关系。一个是说 has_many 用户,一个说它 belongs_to 一个所有者(现有用户)。

公司模式

class Company < ActiveRecord::Base
  belongs_to :owner, class_name: 'User', foreign_key: 'owner_id'
  has_many :users
end

通过告诉我的用户模型 accepted_nested_attributes_for 公司,在设计用户注册中创建公司。

用户模型

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  belongs_to :company
  accepts_nested_attributes_for :company
end

设计用户注册视图

.section.first.dark-grey.p-b-20
  .container
    .grid
      .col-md-6.col-md-offset-3
        %h2.grid-title Sign up
        = form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
          = devise_error_messages!
          .form-row
            = f.email_field :email, autofocus: true, class: "form-control", placeholder: "email address"
          .form-row
            = f.password_field :password, autocomplete: "off", class: "form-control", placeholder: "password"
          .form-row
            = f.password_field :password_confirmation, autocomplete: "off", class: "form-control", placeholder: "confirm password"
          = f.fields_for :company_attributes do |ff|
            .form-row
              = ff.text_field :name, class: "form-control", placeholder: "company name"
          .form-row
            = f.submit "Sign up", class: "btn btn-primary btn-cons"
        = render "devise/shared/links"

最后,我覆盖设计用户注册控制器,添加逻辑以设置公司所有者

覆盖设计注册控制器

class RegistrationsController < Devise::RegistrationsController
  before_filter :configure_permitted_parameters

    #GET /users/sign_up
    def new
      # Override Devise default behaviour and create a company as well
      build_resource({})
      resource.build_company
      respond_with self.resource
    end

    #POST /users/sign_up
    def create
      # Let devise create user and company using nested attributes
      super 
      # Set the owner of the newly created company as new user
      company = resource.company
      company.owner_id = resource.id
      company_saved = company.save
      if company_saved == false
        resource.destroy
        company.destroy
        return new_user_registration_path
      end  
    end

  protected

  def configure_permitted_parameters
      devise_parameter_sanitizer.for(:sign_up) { |u|
        u.permit(:email, :password, :password_confirmation, :company_attributes => :name)
      }
    end
end

2 个答案:

答案 0 :(得分:3)

Reddit post上,添加attr_accessor :owner_id似乎可以解决问题。这表明测试数据库模式确实是问题,正如@HermanHiddema建议的那样。您可以执行RAILS_ENV=test rake db:schema:load或类似操作来删除现有架构并从头开始重新创建,而不是db:test:prepare(在4.1中删除)。

maintain_test_schema!如果架构版本与数据库版本不同,则似乎只加载架构。因此,如果您修改了已经运行的迁移(作为一个示例),则不会检测到需要重置测试模式。

答案 1 :(得分:2)

你有没有运行rake db:test:prepare?如果您的测试数据库尚未在公司表上有owner_id列,则可能会出现这样的错误。