13

Is there a hook or callback that I can implement so that right after the user is created, I would like to invoke some custom code ?

I tried after_confirmation hook in the user model but that didn't work.

ed1t
  • 8,719
  • 17
  • 67
  • 110

3 Answers3

20

Use the standard after_create callback provided by Rails.

class User < ActiveRecord::Base
  after_create :do_something

  def do_something
    puts "Doing something"
  end
end
Ryan Bigg
  • 106,965
  • 23
  • 235
  • 261
  • How can I use this to access the user? For example I want to give a user a default role using Royce, so is it just `@user`, so I can do `@user.add_role :user` – Un3qual Jan 21 '15 at 15:53
  • If you're on Rails 4 with Devise 3.5, see my answer [below](http://stackoverflow.com/a/35478495/214446), as the `after_create` hook prevented sending confirmation emails for me. – mb21 Feb 18 '16 at 10:13
9

Using a callback is perfectly legit if you're dealing with the internal state of the model you created.

After creating a User, I needed to create default a Team. It's preferable to avoid using callbacks to deal with other objects.

“after_*” callbacks are primarily used in relation to saving or persisting the object. Once the object is saved, the purpose (i.e. responsibility) of the object has been fulfilled, and so what we usually see are callbacks reaching outside of its area of responsibility, and that’s when we run into problems.

From this awesome blog post.

In this case it's better to act on the controller, where you can add your functionality directly, or delegate to a service for an even cleaner solution:

# shell
rails g devise:controllers users

# config/routes.rb
devise_for :users, controllers: { registrations: "users/registrations" }

# app/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
  after_action :create_default_team, only: :create

  private

  def create_default_team
    Team.create_default(@user) if @user.persisted?
  end
end
ecoologic
  • 10,202
  • 3
  • 62
  • 66
6

I'm using Rails 4 with Devise 3.5 with confirmable and had to do this due to various surprises.

class User < ActiveRecord::Base
  # don't use after_create, see https://github.com/plataformatec/devise/issues/2615
  after_commit :do_something, on: :create

  private

    def do_something
      # don't do self.save, see http://stackoverflow.com/questions/22567358/
      self.update_column(:my_column, "foo")
    end
end
mb21
  • 34,845
  • 8
  • 116
  • 142