Create another model upon user new registration in

2019-03-11 18:31发布

问题:

I'm using devise to do the new user registration. Right after a new user is created, I would also like to create a profile for that user.

My create method in the registrations_controller.rb is as follows:

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

But, it is not creating a new Profile and neither is the field for @user.default_card is being filled in. How can I create a new Profile automatically upon each new user registration with devise?

回答1:

I would put this functionality into an before_create callback function on the user model since it is essentially model logic, would only not add another save call and is just generally more elegant.

One possible reason why your code is not working is that @profile = Profile.create is not executed successfully because it is failing validations or something. This would result in @profile.id being nil and thus @user.default_card is nil.

Here is how I would implement this:

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

In your code(or mine), you can always put a simple puts to check if the new profile is getting created. i.e. puts (@profile = Profile.create)



回答2:

Another method in the similar lines is this ( use the build_profile method ) :

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