2015-12-07 111 views
1

考慮以下在application_controller.rb中before_action/filter是一個不好的做法嗎?

class ApplicationController < ActionController::Base 
    # Prevent CSRF attacks by raising an exception. 
    # For APIs, you may want to use :null_session instead. 
    protect_from_forgery with: :exception 

    before_filter :maintenance_mode 

private 

def maintenance_mode 
     @settings = Setting.first 
     if @settings.maintenance 
     if logged_in? 
      if !current_user.admin? 
      redirect_to maintenance_url 
      end 
     else 
      redirect_to maintenance_url 
     end 
     end 

end 

是否有性能問題或不好的做法,一般的在全球範圍內使用before_actions?所以我創建了一個維護模式,如果在數據庫中維護屬性有一個真正的值(這將在我假設的每個請求上進行檢查),並且它可能不是最好的方法,那麼是否有解決方法?

我可以想象在後臺進程中每分鐘檢查一次cron job/rake任務,但是我真正想知道的是before_action總體上是一件壞事嗎?

回答

1

您可以使用您的會話和緩存

class ApplicationController < ActionController::Base 
    # Prevent CSRF attacks by raising an exception. 
    # For APIs, you may want to use :null_session instead. 
    protect_from_forgery with: :exception 

    before_filter :maintenance_mode 

    private 
    def maintenance_mode 
    unless session[:maintainence_mode].present? 
     @settings = Rails.cache.fetch { Setting.first } 
     session[:maintainence_mode] = @settings.maintenance 
    end 

    if session[:maintainence_mode] 
     if logged_in? 
     if !current_user.admin? 
      redirect_to maintenance_url 
     end 
     else 
     redirect_to maintenance_url 
     end 
    end 
    end 
end 

這樣,您就可以撥打before_filter比將大部分的時間是否在session[:maintanence_mode]值設置與否,而不是執行跳過不必要的邏輯和查詢每次查詢。

你也應該使用Rails.cachecookies

使用Rails緩存獲取或得到Setting模型

@settings = Rails.cache.fetch { Setting.first } 

使用cookies儲存價值,而不是session,讓你的支持到期

cookies[:_mmode] = { :value => @settings.maintanence,\ 
    :expires => 1.hour.from_now } 
+0

我可能會丟失一些東西 - 但是如果我現在正在維護模式下訪問您的網站,現在我的會話總是認爲該網站處於維護模式,這看起來不正確;我需要等待會話超時再次使用該站點。糟糕的用戶體驗會影響性能(可能不需要)。 – house9

+0

我同意你的意見,如果你正在講述的話,將它存儲在會話中是一個錯誤。但還有其他替代方法,如Cookie和緩存可能會過期。如果適用於所有用戶,我更喜歡緩存。 –

+0

@MohamedOsama你如何使用這行'@settings = Rails.cache.fetch {Setting.first}',因爲它表示'參數的數量錯誤(0表示1..2)' –

2

我不會認爲before_action比其他任何東西都差。您可能需要在其他控制器上實現skip_before_action某些路由,並且使用控制器助手進行一些重構可能可以避免額外的數據庫查找。總體而言,行動是軌道的主要功能之一,而不是出於性能原因值得避免的事情。

相關問題