简体   繁体   English

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

[英]RSpec/Capybara test failing with no method error for model setter

Short Version 简洁版本

I have added a company model to my rails app which is in the devise user registration view using accepts_nested_attributes on the user model. 我已经在我的Rails应用程序中添加了一个公司模型,该模型在devise用户注册视图中使用用户模型上的accepts_nested_attributes。 The setup works when I run through it manually but when I execute the test it fails with: 当我手动运行安装程序时,该安装程序起作用,但是当我执行测试时,安装失败并显示以下内容:

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

How can I fix this error? 如何解决此错误? I am not sure what it is telling me. 我不确定它在告诉我什么。

The test code which is in spec/features: 规范/功能中的测试代码:

authentication_flows_spec.rb 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

Long Version 长版

Recently I have added a Company model to my app which has two relationships. 最近,我在我的应用程序中添加了具有两种关系的公司模型。 One to say it has_many users and one to say it belongs_to an owner (which is a existing user). 一个说它HAS_MANY用户和一个说它belongs_to的所有者(其为现有的用户)。

Company Model 公司模式

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

The company is created in the devise user registration by telling my user model to accepts_nested_attributes_for the company. 通过告诉我的用户模型该公司的accepts_nested_attributes_devise用户注册中创建该公司。

User Model 用户模型

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

Devise User Registration View 设计用户注册视图

.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"

Finally I override the devise user registrations controller to add the logic to set the owner of the company 最后,我重写了devise用户注册控制器,添加了设置公司所有者的逻辑

Overriden Devise Registrations Controller 覆盖设计注册控制器

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

On your Reddit post , adding attr_accessor :owner_id seemed to resolve the problem. 在您的Reddit帖子上 ,添加attr_accessor :owner_id似乎可以解决问题。 That suggests that the test db schema really is the problem as @HermanHiddema suggests. 这表明测试数据库模式确实是@HermanHiddema建议的问题。 Instead of db:test:prepare (removed in 4.1), you could do RAILS_ENV=test rake db:schema:load or similar to drop the existing schema and recreate from scratch. 代替db:test:prepare(在4.1中删除),您可以执行RAILS_ENV=test rake db:schema:load或类似的操作来删除现有模式并从头开始创建。

maintain_test_schema! maintain_test_schema! appears to only load the schema if you the schema version is different from the one in the DB. 如果架构版本与数据库中的版本不同,则似乎仅加载架构。 So if you modified migrations that had already run (as one example), it wouldn't detect that the test schema needs to be reset. 因此,如果您修改了已经运行的迁移(作为一个示例),则不会检测到需要重置测试模式。

Have you run rake db:test:prepare? 您是否运行过rake db:test:prepare? If your test database does not have an owner_id column on the companies table yet, you could get an error like this. 如果您的测试数据库在companies表上还没有owner_id列,则可能会出现类似的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM