短版
我已经在我的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
答案 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列,则可能会出现这样的错误。