开发者

Rails routing-filter, parameters not present

I'm trying to sort out the routing for a multinational web store which only has a presence in certain countries. Each store is different and has a different catalogue of products and there is also a world-wide store for all other countries. I have set up Nginx to prepend the two letter country code from an lookup of the user's IP address so that my Rails app can figure which store to direct the visitor to. I then use Sven Fuch's excellent routing-filter to capture that code, do a lookup against a global SHOPS object and if a match is found then the country code is used, otherwise they get the default (world-wide) store. My routing filter currently looks like this:

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

Now the curious thing is, the params collection does not contain a :shop param when the around_generate method is executed. My code is directly based on the pagination filter included with the routing-filter gem (I'm not using the开发者_高级运维 locale filter as each of these stores is also multilingual - i18n is handled using accept-language header instead). The original pagination filter by Sven Fuchs looks like this:

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

In my filter, shop = params.delete(:shop) results in a Nil object error and I can see from "puts params" that it is indeed not present. Does anyone have any suggestions as to why I'm unable to store and retrieve the :shop param?

Edit: I should mention that I have checked that the parameter gets set correctly in around_recognize - a "puts" of the params collection here does indeed contain the correct :shop object.


If you don't pass a :shop param to url_for (or whatever url generation helper you use here) it won't be passed to around_generate either. around_generate wraps around the url generation part of the routing system.

The Pagination filter assumes the same, e.g. it would be called like blog_posts_path(:page => 2).

But maybe that's not what you want. If you have a look at the Locale filter then this assumes that you sometimes pass a locale to the url helper but sometimes you don't. If :locale is not given it will look it up from I18n.locale which is the current locale set for this request. Maybe you want something similar here?

You could also have a look at the controller's default_url_options. IIRC you can set a default option here, too, so maybe this could work for you. I'm not using this approach anywhere though, so I'm just guessing.

HTH

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜