【问题标题】:How do I check for validation for redirection to void cyclic redirection loop in ruby on rails?如何检查重定向验证以在 ruby​​ on rails 中使用 void 循环重定向循环?
【发布时间】:2022-10-23 23:18:32
【问题描述】:

我有一个重定向模型,有两列 tofrom。我还有一个前端 UI,可以在其中添加重定向。

我需要知道是否有任何解决方案可以通过创建 before_save 验证或其他方式来避免循环重定向循环。

一些重定向测试用例:

循环重定向 (将导致重定向循环)

1 -> 2
2 -> 3
3 -> 4

4 -> 1

链式重定向 (不会导致重定向循环)

1 -> 2
2 -> 3

4 -> 1

循环重定向 (会导致重定向循环)

1 -> 1

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    如果我理解得很好,基本上你不希望列和列是相同的。做这样的事情很容易。在您的重定向模型中,您可以添加:

    class Redirection < ApplicationRecord
    ...
    
    validate :to_and_from_not_equal
    
    private
    
    def to_and_from_not_equal
      if self.to == self.from
        errors.add(:base, "To and From cannot be equal")
      end
    end
    

    如果两个值相等,则无法创建重定向记录。

    【讨论】:

    • 是的。这适用于具有相同tofrom 的单个重定向记录。我需要验证另一个重定向记录是否导致重定向循环。我会更新这个问题,因为它并不具体。
    • 好的,我明白你的意思了。但我不确定这可以通过简单的 sn-p 代码来完成。此外,当重定向发生创建循环时,解决此问题的解决方案应该是什么?只是阻止用户创建记录? “to”和“from”也是我在回答中假设的URL吗?
    • 是的,我知道这个验证并不简单。可能的解决方案是阻止用户提交记录并返回错误。此外,tofrom 只是路径名,如/public。重定向是使用 react-router-dom 完成的。一个可能的验证思路是使用 BFS 来检查当前重定向记录是否会形成循环图或排序。但我不知道如何在 Rails 中实现这一点。我假设会有一个 rails gem 或 in-build 方法会引发错误,因为重定向循环可能会使应用程序崩溃。
    • 我找到了一个更好的方法来解决这个问题。 def check_redirection_loop if Redirection.find_by(to: self.from).present? if Redirection.find_by(from: self.to).present? errors.add(:base, "This redirection cause a redirect loop") end end end 。但我不知道这是否是执行 ActiveRecordQuery 的 Rails 方式?
    【解决方案2】:
    class Redirection < ApplicationRecord
    ...
    
    validate :to_and_from_not_equal
    validate :check_redirection_loop
    
    private
    
    def to_and_from_not_equal
      if self.to == self.from
        errors.add(:base, "To and From cannot be equal")
      end
    end
    
    def check_redirection_loop
      if to_exist_in_from? && from_exist_in_to?
        errors.add(:base, "This redirection causes redirection loop")
      end
    end
    
    def to_exist_in_from?
      Redirection.where(to: self.from).present?
    end
    
    def from_exist_in_to?
      Redirection.where(from: self.to).present?
    end
    

    这是扩展@Maxence 答案的答案。这现在对我有用。代码库可以改进。

    【讨论】:

      猜你喜欢
      • 2015-03-17
      • 2012-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-07
      • 1970-01-01
      相关资源
      最近更新 更多