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_user
为 nil
时,您不能 build_account
。这对我来说很有意义,但是
- 为什么这种情况只是偶尔发生?
- 在 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
我想在 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_user
为 nil
时,您不能 build_account
。这对我来说很有意义,但是
- 为什么这种情况只是偶尔发生?
- 在 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