Rails-фильтр маршрутизации, параметры отсутствуют - PullRequest
1 голос
/ 12 ноября 2010

Я пытаюсь разобраться в маршрутизации для многонационального интернет-магазина, присутствующего только в определенных странах. Каждый магазин отличается и имеет свой каталог товаров, а также есть магазин по всему миру для всех других стран. Я настроил Nginx для добавления двухбуквенного кода страны к поиску IP-адреса пользователя, чтобы мое приложение Rails могло определить, в какое хранилище направить посетителя. Затем я использую превосходный фильтр маршрутизации Свена Фуча , чтобы захватить этот код, выполнить поиск по глобальному объекту 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

Теперь любопытно, что коллекция params не содержит параметр: shop при выполнении метода around_generate. Мой код напрямую основан на фильтре разбиения на страницы, включенном в гем фильтра маршрутизации (я не использую фильтр локали, поскольку каждое из этих хранилищ также многоязычно - 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, и я могу видеть из «put params», что его действительно нет. У кого-нибудь есть какие-либо предложения относительно того, почему я не могу сохранить и получить параметр: shop?

Редактировать: Я должен упомянуть, что я проверил, что параметр правильно установлен в around_recognize - здесь «put» коллекции params действительно содержит правильный объект: shop.

1 Ответ

3 голосов
/ 12 ноября 2010

Если вы не передадите параметр: shop в url_for (или любой другой помощник по генерации URL, который вы здесь используете), он также не будет передан в around_generate. around_generate оборачивает часть генерирования URL системы маршрутизации.

Фильтр пагинации предполагает то же самое, например, это будет называться как blog_posts_path (: page => 2).

Но, может быть, это не то, что вы хотите. Если вы посмотрите на фильтр Locale, тогда предполагается, что вы иногда передаете локаль помощнику url, но иногда нет. Если: locale не указан, он будет искать его из I18n.locale, который является текущим языковым стандартом, установленным для этого запроса. Может быть, вы хотите что-то подобное здесь?

Вы также можете взглянуть на default_url_options контроллера. IIRC Вы также можете установить здесь опцию по умолчанию, так что, возможно, это сработает для вас. Хотя я нигде не использую этот подход, так что я просто догадываюсь.

НТН

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...