在Rails中确定两个(或者多个)给定URL(作为字符串或者哈希选项)是否相等的最佳方法是什么?

时间:2020-03-06 14:39:09  来源:igfitidea点击:

我想要一个名为same_url的方法吗?如果传入的URL相等,则将返回true。传入的URL可能是params选项哈希或者字符串。

same_url?({:controller => :foo, :action => :bar}, "http://www.example.com/foo/bar") # => true

Rails框架帮助程序current_page?似乎是一个不错的起点,但我想传入任意数量的URL。

作为额外的好处,如果可以传入要从比较中排除的参数散列,那就很好了。因此,方法调用可能类似于:

same_url?(projects_path(:page => 2), "projects?page=3", :excluding => :page) # => true

解决方案

这是我们所追求的吗?

def same_url?(one, two)
  url_for(one) == url_for(two)
end

这是方法(在/ lib中绑定它,并在environment.rb中要求它):

def same_page?(a, b, params_to_exclude = {})
  if a.respond_to?(:except) && b.respond_to?(:except)
    url_for(a.except(params_to_exclude)) == url_for(b.except(params_to_exclude))
  else
    url_for(a) == url_for(b)
  end
end

如果我们使用的是Rails 2.0.1之前的版本,则还需要向Hash添加except帮助器方法:

class Hash
  # Usage { :a => 1, :b => 2, :c => 3}.except(:a) -> { :b => 2, :c => 3}
  def except(*keys)
    self.reject { |k,v|
      keys.include? k.to_sym
    }
  end
end

Rails的更高版本(以及ActiveSupport)已经包含except(来源:Brian Guthrie)

def all_urls_same_as_current? *params_for_urls
  params_for_urls.map do |a_url_hash| 
    url_for a_url_hash.except(*exclude_keys)
  end.all? do |a_url_str|
    a_url_str == request.request_uri
  end
end

其中:

  • " params_for_urls"是一组由url参数组成的哈希值(每个数组条目都是用于构建url的参数)
  • exclude_keys是要忽略的键的符号数组
  • request.request_uri可能与我们应该使用的不完全相同,请参见下文。

然后,在实现版本时,我们需要考虑各种事项:

  • 我们想将整个uri与域,端口和全部,还是仅路径进行比较?
  • 如果只是路径,我们是否仍要比较问号后传递的参数还是构成实际路径路径的参数?