Rails 设计注册时建立一对一关系的错误

Rails Devise error on building one to one relationship upon registration

我想在 Devise 注册时创建一对一关系,用户 -> 帐户。我以为我已经用下面的代码弄明白了。

# account.rb
class Account < ActiveRecord::Base
  belongs_to :user
end

# user.rb
class User < ActiveRecord::Base
  has_one :account
end

# registrations_controller.rb
def create
  super
  current_user.build_account(account_params).save
end

到目前为止,这段代码在大约 80% 的时间内都有效。但是每隔一段时间,我就会收到以下错误。

undefined method 'build_account' for nil:NilClass app/controllers/users/registrations_controller.rb:13:in 'create'

显然,错误告诉我,当 current_usernil 时,您不能 build_account。这对我来说很有意义,但是

  1. 为什么这种情况只是偶尔发生?
  2. 在 Devise 用户注册时建立这种一对一关系的更一致的方法是什么?

当我这样做时,我喜欢使用嵌套表单。

# user.rb
class User < ActiveRecord::Base
  belongs_to :account
  accepts_nested_attributes_for :account
end

# account.rb
class Account < ActiveRecord::Base
  belongs_to :user
end

#views registrations/new.html.haml
  = simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f|
  %ul
    - resource.errors.full_messages.each do |e|
      %li=e
        = f.simple_fields_for :account do |account_form|
          ...
        ...


#Controller
class Users::RegistrationsController < Devise::RegistrationsController
  def new
    resource = build_resource({})
    resource.build_account
    respond_with resource
  end

  def create
    build_resource(sign_up_params)
    if resource.save
      ...
    else
      ...
     end
   end

   private
   def sign_up_params
     allow = [:first_name, :last_name, :phone, :email, :password, :password_confirmation, :agree_newsleter, account_attributes: [:name, :phone, :website]]
     params.require(resource_name).permit(allow)
   end

end