【问题标题】:rails: put and interruption in before filterrails:在过滤器之前放置和中断
【发布时间】:2026-02-03 10:45:01
【问题描述】:

我想要一个像“must_have_permission_to_write”这样的前置过滤器,当用户没有写入权限时调用它会呈现一条消息,说“你不能这样做!”然后返回。

问题是我得到“每个动作只能渲染或重定向一次”当然...... 如何在 before 过滤器中停止执行? 谢谢

【问题讨论】:

    标签: ruby-on-rails ruby authorization render before-filter


    【解决方案1】:

    我认为最简单的答案是添加重定向并返回 false 到您的 must_have_permission_to_write 方法。

    def must_have_permission_to_write
      unless current_user.has_permission?(something)
        redirect_to access_denied_path 
        return false
      end
    end
    

    然后,为某处拒绝访问创建一个操作,添加路由,然后在模板中放置您想要的任何内容。

    【讨论】:

    • 这种“并返回 false”的东西用作模式似乎有点危险。如果 redirect_to 返回 nil,则改为返回 nil。将“return false”放在单独的行上可能是解决此问题的更好方法。
    • 好电话,已解决
    • @tadman +1,不幸的是,它是一种根深蒂固于“Rails 方式”的反模式。我也希望看到它消失。
    【解决方案2】:

    我注意到这里的帖子有几点:

    • 在前置过滤器中调用渲染或重定向将取消操作。 Rails 有一段时间没有这样做,但据我所知,现在这是自动的。我似乎无法在网上找到有关此的参考,如果我错了,请有人纠正我。
    • 如果您实际上在操作中,使用“并返回”是取消操作的好方法。在上面的示例中,方法被定义为一个前置过滤器(即单独的方法),在方法的末尾调用“并返回”,并没有那么有用。
    • 我认为你不应该告诉别人“你不能那样做”,这不是一个非常安全的做法。如果有人要求他们无权要求的东西,则响应应该是 404。这样的响应是在向这个“好奇”的人提供太多信息。

    【讨论】:

      【解决方案3】:

      只需添加and return,就像这样做:

      before_filter :must_have_permission_to_write
      
      def must_have_permission_to_write
        redirect_to login_path and return unless current_user
      end
      

      【讨论】:

      • -1 return 将从方法中返回 nil(而不是从调用它的操作中),这不会做任何事情。您必须从过滤器方法返回false。另外,请参阅 tadman 对 Ben 的回答的回应。