【问题标题】:RSpec/Capybara test failing with no method error for model setterRSpec/Capybara 测试失败,模型设置器没有方法错误
【发布时间】:2014-08-04 18:57:24
【问题描述】:

短版

我已在我的 rails 应用程序中添加了一个公司模型,该应用程序位于设计用户注册视图中,使用用户模型上的接受嵌套属性。设置在我手动运行时有效,但在执行测试时失败:

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

如何解决此错误?我不确定它在告诉我什么。

spec/features 中的测试代码:

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

公司是在设计用户注册时通过告诉我的用户模型accepts_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

【问题讨论】:

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


    【解决方案1】:

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

    维护_test_schema!如果架构版本与数据库中的版本不同,似乎只加载架构。因此,如果您修改了已经运行的迁移(例如),它不会检测到需要重置测试架构。

    【讨论】:

    • 嘿,谢谢 - 在你发帖之前我昨晚又试了一下,结果证明你是对的 :) 这归结为 rails 中的一个错误(回滚迁移更改然后应用不是' t 反映在测试数据库中。github.com/rails/rails/issues/15787) rake db:test:clone 修复了它。稍后我会在 Reddit 上写一篇更完整的文章。
    【解决方案2】:

    您是否运行过 rake db:test:prepare?如果您的测试数据库在公司表中还没有 owner_id 列,您可能会收到类似这样的错误。

    【讨论】:

    • 不幸的是,这对我不起作用,因为我使用的是 Rails 4,所以测试数据库会自动为我管理。我相信这条线:ActiveRecord::Migration.maintain_test_schema!在 RSpec 的 rails_helper.rb 中,我也这样做了。 (但无论如何我都试过了!)。但仍然感谢您阅读它。
    猜你喜欢
    • 2015-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-09
    • 2013-12-10
    • 1970-01-01
    相关资源
    最近更新 更多