2015-09-26 160 views
0

我想要什麼:使用設計用戶註冊,登錄等...當用戶註冊並確認後,我想創建一堆用戶默認模板該用戶。設計:在用戶確認後設置用戶默認模板

我試過的: 我試圖覆蓋Confirmations#show,這樣show.html.erb就會成爲視圖,成功確認後會調用#setup_user_defaults()。 類ConfirmationsController設計:: ConfirmationsController

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

我不斷收到,說我只能有1個重定向或在動作中渲染錯誤。有這種觀點對我來說很重要的原因是因爲#setup_user_defaults()需要一些時間來舒適,用戶可能會刷新或什麼東西搞砸的過程

我的想法:我是一個新手,並沒有瞭解了背景工作呢。所以,我的問題是:這是一個背景工作嗎?或者,如何讓#顯示「您的帳戶正在設置,這可能需要幾分鐘時間」。沒有使用AJAX(我現在還沒有)。

還是其他想法?

回答

0

由於您打電話給render,所以您會收到錯誤,然後您打電話給super,其中也有一個呈現或重定向。您不能在方法中多次調用渲染或重定向(除非將其封裝到條件if語句中)。

此外,您不需要空圓括號來調用像JavaScript一樣的方法。

現在。任何大型或緩慢運行的任務都適用於後臺。即使你是新手,如果你使用的是rails 4.2,那麼今天的後臺工作非常簡單!

我會使用delayed_job,它的方便和靈活。因此,這些步驟如下:

1.添加的delayed_job和守護程序到您的Gemfile &運行捆綁安裝

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 

如果你寧願做它的控制器,你可以但色器件記住一定要做在註冊控制器內部,所以當新用戶註冊,它的創建方法發生了:

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 

此外,如果你使用的是麒麟和領班爲您的應用服務器有你需要採取其他步驟,BU t那些在教程和這裏在StackOverflow概述,所以只是搜索或創建一個新的問題,如果你被卡住

+0

我通過你很清楚的教程走了,我也看了看文檔,但我很困惑。我認爲'handle_asynchronously'的重點是我不必退出rails服務器,然後運行'rake jobs:work',然後退出並再次運行rails s?我不明白delayed_job是如何工作的。你能否指點我關於delayed_jobs的教程或者解釋這個使用delayed_job的過程?謝謝一堆 – v8soup

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完成。一旦成功,最終將他們重定向到他們的個人資料或任何你想要的。

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/