Rails路由过滤器,参数不存在

时间:2010-11-12 09:03:29

标签: ruby-on-rails ruby parameters routing filter

我正在尝试为一家只在某些国家/地区开展业务的跨国网店进行整理。每个商店都不同,有不同的产品目录,还有一个适用于所有其他国家的世界商店。我已经设置了Nginx,以便在查找用户的IP地址时添加两个字母的国家/地区代码,以便我的Rails应用程序可以确定将访问者指向哪个商店。然后我使用Sven Fuch's excellent routing-filter来捕获该代码,对全局SHOPS对象进行查找,如果找到匹配项,则使用国家/地区代码,否则它们将获得默认(全球)存储。我的路由过滤器目前如下所示:

module RoutingFilter
  class Country < Filter

    countries_pattern ||= %r(^/(?i)([a-zA-Z]{2})(?=/|$))

    def around_recognize(path, env, &block)
      country = "#{extract_segment!(countries_pattern, path)}".upcase
      yield(path, env).tap do |params|
        params[:shop] = SHOPS.fetch(country.to_sym) || DEFAULT_SHOP
      end
    end

    def around_generate(params, &block)
      puts params
      shop = params.delete(:shop)
      yield.tap do |result|
        prepend_segment!(result, shop[:country_code]) if shop
      end
    end
  end
end

现在奇怪的是,当执行around_generate方法时,params集合不包含:shop param。我的代码直接基于路由过滤器gem包含的分页过滤器(我没有使用语言环境过滤器,因为这些商店中的每一个也是多语言的 - 而i18n是使用accept-language标头来处理的)。 Sven Fuchs的原始分页过滤器如下所示:

module RoutingFilter
  class Pagination < Filter
    PAGINATION_SEGMENT = %r(/page/([\d]+)/?$)

    def around_recognize(path, env, &block)
      page = extract_segment!(PAGINATION_SEGMENT, path)
      yield(path, env).tap do |params|
        params[:page] = page.to_i if page
      end
    end

    def around_generate(params, &block)
      page = params.delete(:page)
      yield.tap do |result|
        append_segment!(result, "page/#{page}") if append_page?(page)
      end
    end

    protected

      def append_page?(page)
        page && page.to_i != 1
      end
  end
end

在我的过滤器中,shop = params.delete(:shop)导致Nil对象错误,我可以从“puts params”看到它确实不存在。有没有人有任何建议,为什么我无法存储和检索:商店参数?

编辑:我应该提一下,我已经检查过参数在around_recognize中设置正确 - 这里的params集合的“puts”确实包含正确的:shop对象。

1 个答案:

答案 0 :(得分:3)

如果你没有将:shop param传递给url_for(或者你在这里使用的任何url生成助手),它也不会传递给around_generate。 around_generate包裹路由系统的url生成部分。

分页过滤器假设相同,例如,它将被称为blog_posts_path(:page =&gt; 2)。

但也许这不是你想要的。如果您查看了Locale过滤器,那么这假定您有时会将区域设置传递给url帮助程序,但有时则不会。如果:未给出语言环境,它将从I18n.locale查找,这是为此请求设置的当前语言环境。也许你想要类似的东西?

您还可以查看控制器的default_url_options。 IIRC你也可以在这里设置一个默认选项,所以这可能适合你。我不是在任何地方使用这种方法,所以我只是在猜测。

HTH