Изобретать после создания крючка

Есть ли крючок или обратный вызов, который я могу реализовать, так что сразу после создания пользователя я хотел бы вызвать какой-то пользовательский код?

Я попробовал hook_name в пользовательской модели, но это не сработало.

Ответ 1

Используйте стандартный обратный вызов after_create, предоставляемый Rails.

class User < ActiveRecord::Base
  after_create :do_something

  def do_something
    puts "Doing something"
  end
end

Ответ 2

Я использую Rails 4 с Devise 3.5 с confirmable и должен был сделать это из-за различных неожиданностей.

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

Ответ 3

Использование обратного вызова совершенно законно, если вы имеете дело с внутренним состоянием созданной модели.

После создания User мне нужно было создать по умолчанию Team. Рекомендуется избегать использования обратных вызовов для работы с другими объектами.

"after_ *" обратные вызовы в основном используются в отношении сохранения или сохранения объекта. После сохранения объекта цель (то есть ответственность) объекта была выполнена, и поэтому мы обычно видим обратные вызовы, выходящие за пределы своей области ответственности, и это когда мы сталкиваемся с проблемами.

Из этого удивительного сообщения в блоге.

В этом случае лучше действовать на контроллере, где вы можете напрямую добавить свою функциональность или делегировать службе для еще более чистого раствора:

# 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