用户在设计中进行新注册时创建另一个模型

时间:2011-12-01 07:06:40

标签: ruby-on-rails ruby-on-rails-3 devise

我使用devise进行新用户注册。在创建新用户之后,我还想为该用户创建配置文件。

create中的registrations_controller.rb方法如下:

class RegistrationsController < Devise::RegistrationsController
    def create
      super
      session[:omniauth] = nil unless @user.new_record?

      # Every new user creates a default Profile automatically
      @profile = Profile.create
      @user.default_card = @profile.id
      @user.save

    end

但是,它没有创建新的配置文件,也没有填写@ user.default_card的字段。如何在每个新用户注册时自动创建新的配置文件?

2 个答案:

答案 0 :(得分:6)

我会将此功能放入用户模型的before_create回调函数中,因为它本质上是模型逻辑,只会添加另一个保存调用,而且通常更优雅。

您的代码无效的一个可能原因是@profile = Profile.create未成功执行,因为它验证失败或其他原因。这会导致@profile.idnil,因此@user.default_cardnil

以下是我将如何实现这一点:

class User < ActiveRecord::Base

  ...

  before_create :create_profile

  def create_profile
    profile = Profile.create
    self.default_card = profile.id
    # Maybe check if profile gets created and raise an error 
    #  or provide some kind of error handling
  end
end

在您的代码(或我的代码)中,您始终可以使用简单的puts来检查是否已创建新的配置文件。即puts (@profile = Profile.create)

答案 1 :(得分:0)

类似行中的另一种方法是这样的(使用build_profile方法):

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, :async,
         :recoverable, :rememberable, :trackable, :validatable, :omniauthable, omniauth_providers: [:facebook]


  has_one :profile

  before_create :build_default_profile

  private
  def build_default_profile
    # build default profile instance. Will use default params.
    # The foreign key to the owning User model is set automatically
    build_profile
    true # Always return true in callbacks as the normal 'continue' state
    # Assumes that the default_profile can **always** be created.
    # or
    # Check the validation of the profile. If it is not valid, then
    # return false from the callback. Best to use a before_validation
    # if doing this. View code should check the errors of the child.
    # Or add the child's errors to the User model's error array of the :base
    # error item
  end
end