2015-12-07 60 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某些路由,并且使用控制器助手进行一些重构可能可以避免额外的数据库查找。总体而言,行动是轨道的主要功能之一,而不是出于性能原因值得避免的事情。

相关问题