Skip to main content

Create a User Profile after saving a Devise User

Gems / Libraries • Asked by Jason Brown

I want to have a user profile instance created in the database which is associated with a newly created devise user. The profile should be created only once and have a user_id associated with the newly created devise user. A few things are confusing me..

  1. The action should happen atomicly. Either the whole things succeeds or the whole thing fails. Orphaned profiles are users created without profiles wouldn't be good. How to do this?

  2. At the time devise creates a user, the current_user variable isn't available as the user is not logged in. Configuring devise to login automatically after account creation could work but what if I change my mind and don't want this in the future. So I need a way to associate a user_id with a profile w/o using the current_user so my app can stay flexible.

  3. Is there a better approach that I'm missing? I'm looking for the correct solution instead of just a solution. Toying around with the user_model the wrong way feels dangerous and I want to do the right thing. I'd really enjoy hearing your opinions how best to do this in a way that doesn't go against the RoR framework and keeps things clear, flexible and maintainable.

Gravatar Chris Oliver commented on : Mod Staff
  1. When the user registers, do you want to have them fill out some of the profile information as well? If so, then I would recommend updating the Devise form to be a nested form. That way you create both together at once using accepts_nested_attributes_for.

  2. When Devise creates a user, it does actually sign them in as soon as they're persisted to the database (it would be weird if you registered and then had to login immediately).

  3. Depends on what you want to accomplish really. If you want two things filled out at once, the above solution in #1 is great and pretty painless.

The other option is just to create a blank profile during the registration process if that's what you're looking for. In this case, I would override the Devise controller, copy the create action, and then add in code on the save part to also create and save your profile for the resource.

For example, you could modify the default create action to look like this which would provide an atomic method of creating both the user and the profile:

class Devise::RegistrationsController
  def create
    yield resource if block_given?
    if resource.persisted?

      # We know that the user has been persisted to the database, so now we can create our empty profile

      if resource.active_for_authentication?
        set_flash_message! :notice, :signed_up
        sign_up(resource_name, resource)
        respond_with resource, location: after_sign_up_path_for(resource)
        set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
        respond_with resource, location: after_inactive_sign_up_path_for(resource)
      clean_up_passwords resource
      respond_with resource

I changed this in config/routes.rb

devise_for :users,
             controllers: { registrations: "devise_override/registrations" }

Then did an override of the Devise create and destroy actions

class DeviseOverride::RegistrationsController < Devise::RegistrationsController
  def create
    super # this calls Devise::RegistrationsController#create as usual
    # after creating a new user, create a profile that has
    # the profile.user_id field set to the user_id of the user jsut created
        @profile =
        @profile.user_id =

  def destroy
    if resource.destroy
        @profile = Profile.find(user_id:

Is there a downside to this approach?

Gravatar Chris Oliver commented on : Mod Staff

Looks pretty good. I think if you have the has_one and belongs_to associations setup on User and profile, I would modify your create like this:


That'll be a little cleaner and easier to maintain.

For the destroy, it might make more sense to use a dependent: :destroy callback on the User models: has_one :profile, dependent: :destroy. This way anytime you destroy a user, you can also destroy their profile. It will happen automatically.

Hello @JasonBrown - I'm trying to do exactly what you described. Did your solution work? Any example code you care to share? Thanks!

Yes, it worked fine but I wouldn't do it again. I'd use lazy instantiation instead. Create the user profile only when the user tries to access it but it doesn't yet exist. Another approach, just add fields to the devise user model and be more specific in your queries (in other words don't SELECT * ) so you aren't caching or loading all the user profile information with each request. Either way works. I'd go with lazy instantiation personally.

Unless I'm missing something, I think this is the simplest way and doesn't require modifying your devise controller:

class User < ActiveRecord::Base

  has_one :profile, dependent: :destroy
  after_create :init_profile

  def init_profile


Even better, Thank you Jacob. I'll fire up a toy project and write some tests just to make sure it works.

This is awesome, but is there a way to do it, get a and still be able to do something like this later:

# profile.rb
validates_presence_of :name, :bio

You could do something like this:

class User < ApplicationRecord
  has_one :profile
  after_create :init_profile

  def init_profile false)

This lets you create the records but if you have other functions that check if profile.valid? then it would return false, and this may not be the desired result. See: Notice they're talking about the on: :update, which isn't what we're doing here, however the side effect is the same.

Login or create an account to join the conversation.