before_action/filter 在 application_controller.rb 中是一种不好的做法吗?

Is before_action/filter in application_controller.rb a bad practice?

考虑以下因素

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 通常是一件坏事?

我不会认为 before_action 比其他任何东西都差。您可能需要在某些路由的其他控制器中实现 skip_before_action,并且使用控制器助手进行一些重构可能可以避免额外的数据库查找。总的来说,before 动作是 rails 的主要实用工具,出于性能原因不值得避免。

您可以使用会话和缓存跳过不必要的逻辑和查询

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 }