设计:在用户确认后设置用户默认模板

时间:2015-09-26 14:55:01

标签: ruby-on-rails devise confirmation

我想要的:使用Devise进行用户注册,登录等...当用户注册并确认后,我想为该用户创建一堆用户默认模板。

我尝试过的: 我试图覆盖Confirmations#show,以便show.html.erb成为视图,并在成功确认后调用#setup_user_defaults()。     class ConfirmationsController Devise :: ConfirmationsController

    def show
      render('show')
      setup_user_defaults()
      super
    end

我一直收到错误消息,说明我只能在动作中进行1次重定向或渲染。之所以拥有这个视图对我来说很重要,是因为#setup_user_defaults()需要一点点太长时间才能让用户感觉舒适,或者某些东西搞砸了这个过程

我的想法:我是一个新手,还没有了解后台工作。所以,我的问题是:这是一份后台工作吗?或者我怎样才能让#show看到“您的帐户正在设置中。这可能需要几分钟时间。”不使用AJAX(我现在还没有)。

还是其他任何想法?

2 个答案:

答案 0 :(得分:0)

您收到错误是因为您正在调用render,然后您正在调用super,其内部也有渲染或重定向。您无法在方法中多次调用渲染或重定向(除非将其封装到条件if语句中)。

此外,您不需要空括号,以便像调用javascript一样调用方法。

现在。任何大型或慢速运行任务都是后台处理的理想选择。即使你是新手,如果你正在使用rails 4.2,那么背景工作现在很简单!

我会使用delayed_job,它简单灵活。所以这些是步骤:

<强> 1。将delayed_job和守护进程添加到您的gemfile&amp;运行捆绑安装

gem 'delayed_job_active_record'
gem 'daemons'

<强> 2。确保设置模板的方法在用户模型

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable, :confirmable,
         :recoverable, :rememberable, :trackable, :validatable

  def set_default_templates
    ### this is where all your setup code will go, remember that you're inside the object itself, so if you need to reference data stored already you'll use self, e.g. self.name or self.confirmed_at
  end
  handle_asynchronously :set_default_templates
end

注意 确保使用方法名称添加handle_asyncronously行,这告诉模型应始终使用ActiveJob调用此方法(这是包装器,它允许您使用您想要的任何后台服务,但您的代码在模式下没有变化)

第3。现在是时候调用方法,2个选择:从控制器调用方法,或在after_create回调中调用方法

我建议在after_create中执行此操作,它只是更清洁一点。因此,在您的模型中,使用与上面相同的代码,但在设计声明中添加此行:

after_create :set_default_tempaltes

如果您希望在控制器中执行此操作,可以但请记住,必须在注册控制器内完成,所以当新用户注册时,它会在create方法中发生:

def create
  super
  if resource.save
    resource.set_default_templates
  end
end

注意 知道在你完全理解这些设计方法的作用之前,我不建议覆盖它们,并认为你是这样做的。使用after_create回调

更安全

<强> 4。现在生成您的延迟工作

rails generate delayed_job:active_record

<强> 5。从命令行启动后台进程

bin/delayed_job start

此外,如果您正在为应用程序服务器使用独角兽和工头,那么您还需要采取其他步骤,但这些步骤在教程中和StackOverflow中进行了概述,因此只需搜索或创建一个新问题如果你卡住了

答案 1 :(得分:0)

您不能double render来自同一操作的同一页面。但是你可以将它们分成两个动作。首先确保电子邮件确认成功,如果是,请将其重定向到其他操作(必须覆盖devise's Confirmations#show而不调用super):

def show
  self.resource = resource_class.confirm_by_token(params[:confirmation_token])
  yield resource if block_given?

  if resource.errors.empty?
    flash[:notice] = "Your account is being set up. This may take a few minutes. 
                      Please wait to be redirected."
    redirect_to setup_defaults_path
  else
    respond_with_navigational(resource.errors, status: :unprocessable_entity){ render :new }
  end
end

在第二个操作中,当用户等待setup_user_defaults完成时,应显示上面设置的Flash消息。一旦成功,最后将它们重定向到他们的个人资料或任何你想要的。

def setup_defaults
  if setup_user_defaults()
    redirect_to after_confirmation_path_for(resource_name, resource)
  end
end

理想情况下,您可以创建一个后台作业,但要实现您想要做的事情,上面应该这样做。我希望有所帮助!

此处还有一个关于背景处理的精彩教程:sidekiq:https://ryanboland.com/blog/writing-your-first-background-worker/