【问题标题】:Application Controller level validation with redirect使用重定向的应用程序控制器级别验证
【发布时间】:2026-02-06 04:15:01
【问题描述】:

我不确定确保每个用户都有一些必要属性的最佳方法是什么,如果他们没有,我想将他们重定向到“新”页面,例如

class ApplicationController < ActionController::Base
  protect_from_forgery
  before_filter :authenticate_user!, :valid_location

  def valid_location
    if (current_user.location.nil? || current_user.location.city.nil?)
      redirect_to new_user_locations_path(current_user.id)
     else
       true
    end
end

上面的例子是有缺陷的,因为它创建了一个重定向循环。我可以明确地使用一些建议来创建这种验证。谢谢

【问题讨论】:

  • 在位置控制器中,只需添加skip_before_filter :valid_location, only: :new 即可修复重定向循环。而且,您不需要返回 true,因此只需删除 else 部分。

标签: ruby-on-rails ruby-on-rails-3 validation


【解决方案1】:

创建重定向循环的原因是valid_location 方法也在负责new_user_locations_path 的控制器上被调用。为了防止这种情况,您需要确保控制器不会使用skip_before_filter(Rails 4 中的skip_before_action)运行该过滤器。一个类似的问题是answered here

class LocationsController < ApplicationController
  skip_before_filter :valid_location, only: [:new, :create]
  #...
end

因为valid_location 返回一个真/假布尔值,我建议将方法重命名为valid_location?invalid_location? 并稍微重构一下逻辑:

class ApplicationController < ActionController::Base
  protect_from_forgery
  before_filter :authenticate_user!, :redirect_invalid_locations

  private
  def redirect_invalid_locations
    redirect_to(new_user_locations_path(current_user)) if invalid_location?
  end

  def invalid_location?
    current_user.try(:location).try(:city).nil?
  end
end


class LocationsController < ApplicationController
  skip_before_filter :redirect_invalid_locations, only: [:new, :create]
end    

【讨论】:

  • 非常感谢。我只需要改变一件小事。添加:创建到:skip_before_filter:redirect_invalid_locations,仅:[:new,:create]否则我得到:过滤器链停止为:redirect_invalid_locations呈现或重定向