yaroslav / russian

Russian language support for Ruby and Rails | Поддержка русского языка для Ruby и Rails
MIT License
475 stars 127 forks source link

I18n::InvalidPluralizationData для en локали при использовании gem russian #29

Closed dadittoz closed 12 years ago

dadittoz commented 12 years ago

После установки свежей 0.6.0 версии возникает проблема при использовании en локали.

I18n::InvalidPluralizationData in Library_folders#show 
translation data {:other=>"%{count} months", :one=>"1 month"} can not be used with :count => 2

Код

time_ago_in_words(file.upload_date)

При использовании русской локали проблемы нет. Также проблема НЕ возникает если использовать форк git://github.com/kelvich/russian.git

ruby 1.8.7 rails 3.1.1 actionpack (3.1.1)

yaroslav commented 12 years ago

Там форк совсем старый, видимо в 0.2.x проблемы просто не возникало: сейчас попробую повторить.

yaroslav commented 12 years ago

Пока не повторяется (ruby 1.8.7, забандлен rails 3.1.1):

ree-1.8.7-2010.02 :004 > ApplicationController.helpers.time_ago_in_words 2.months.ago
 => "2 months" 
ree-1.8.7-2010.02 :005 > ApplicationController.helpers.time_ago_in_words 35.days.ago
 => "about 1 month" 
ree-1.8.7-2010.02 :006 > ApplicationController.helpers.time_ago_in_words 65.days.ago
 => "2 months" 
ree-1.8.7-2010.02 :007 > ApplicationController.helpers.time_ago_in_words 85.days.ago
 => "3 months" 
ree-1.8.7-2010.02 :008 > I18n.locale = :ru
 => :ru 
ree-1.8.7-2010.02 :009 > ApplicationController.helpers.time_ago_in_words 35.days.ago
 => "около 1 месяц\320\260" 

EDIT: вот что у меня с «голым» приложением, которое я использую для проверки релизов:

➜  cat Gemfile
source 'http://rubygems.org'

gem 'rails', '3.1.1'

gem 'sqlite3'
gem 'thin'

gem 'russian', '0.6.0'

➜  ls -l config/locales 
total 16
-rw-r--r--  1 yaroslav  staff  213 22 окт 16:25 en.yml
-rw-r--r--  1 yaroslav  staff  131 22 окт 16:36 ru.yml
➜  cat config/locales/en.yml 
# Sample localization file for English. Add more files in this directory for other locales.
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.

en:
  hello: "Hello world"
➜  cat config/locales/ru.yml 
ru:
  hello: "Привет"
yaroslav commented 12 years ago

Посмотрите, не осталось ли у вас следов старых версий или форков russian, и покажите по возможности ваши файлы локали (config/locales в Rails). Такое ощущение, что у вас где-то переписан файл английской локали, и там нет значения для en.datetime.distance_in_words.x_months.

С рельсами идет корректный файл локали для английского (duh), значит, вы где-то можете его оверрайдить.

dadittoz commented 12 years ago

Видимо проблема действительно где-то у меня. Сейчас создал новый проект, тесты нормально проходят. А с существующим проектом такая беда :( Буду ковырять. Прошу прощение за false positive.

dadittoz commented 12 years ago

Проблема возникает при

config.i18n.fallbacks = true
config.i18n.default_locale = :ru
yaroslav commented 12 years ago

И все равно, даже если есть fallbacks, у вас должен быть перевод для distance_in_words, так что фолбека происходить не должно. Я перепроверю, но проверкой наличия всех нужных переводов это точно должно решаться.

yaroslav commented 12 years ago

Ну да, проверил. Код здесь, кажется, не при чем — сообщение ровно о том, что для русской плюрализации у вас не хватает данных в локали. Если используется russian или просто правильный набор переводов, такой ошибки не будет.

dadittoz commented 12 years ago

Ярослав,

Вы простите мою настойчивость. Но боюсь все-таки не у меня проблема. Я вот сейчас создал голое приложение rails. Попробуйте у себя пожалуйста склонировать git://github.com/dadittoz/russian-rails-test.git

И дальше сделать это. Если у Вас все будет работать, я убежусь в том, что я не прав.

$ rails console
Loading development environment (Rails 3.1.1)
irb(main):001:0> I18n.locale = :en
=> :en
irb(main):002:0> ActionController::Base.helpers.time_ago_in_words 2.months.ago
I18n::InvalidPluralizationData: translation data {:one=>"1 month", :other=>"%{count} months"} can not be used with :count => 2
    from /usr/lib/ruby/gems/1.9.1/gems/i18n-0.6.0/lib/i18n/backend/pluralization.rb:37:in `pluralize'
    from /usr/lib/ruby/gems/1.9.1/gems/i18n-0.6.0/lib/i18n/backend/base.rb:40:in `translate'
    from /usr/lib/ruby/gems/1.9.1/gems/i18n-0.6.0/lib/i18n/backend/fallbacks.rb:44:in `block (2 levels) in translate'
    from /usr/lib/ruby/gems/1.9.1/gems/i18n-0.6.0/lib/i18n/backend/fallbacks.rb:43:in `catch'
    from /usr/lib/ruby/gems/1.9.1/gems/i18n-0.6.0/lib/i18n/backend/fallbacks.rb:43:in `block in translate'
    from /usr/lib/ruby/gems/1.9.1/gems/i18n-0.6.0/lib/i18n/backend/fallbacks.rb:42:in `each'
    from /usr/lib/ruby/gems/1.9.1/gems/i18n-0.6.0/lib/i18n/backend/fallbacks.rb:42:in `translate'
    from /usr/lib/ruby/gems/1.9.1/gems/i18n-0.6.0/lib/i18n.rb:156:in `block in translate'
    from /usr/lib/ruby/gems/1.9.1/gems/i18n-0.6.0/lib/i18n.rb:152:in `catch'
    from /usr/lib/ruby/gems/1.9.1/gems/i18n-0.6.0/lib/i18n.rb:152:in `translate'
    from /usr/lib/ruby/gems/1.9.1/gems/activesupport-3.1.1/lib/active_support/option_merger.rb:22:in `method_missing'
    from /usr/lib/ruby/gems/1.9.1/gems/actionpack-3.1.1/lib/action_view/helpers/date_helper.rb:95:in `block in distance_of_time_in_words'
    from /usr/lib/ruby/gems/1.9.1/gems/activesupport-3.1.1/lib/active_support/core_ext/object/with_options.rb:41:in `with_options'
    from /usr/lib/ruby/gems/1.9.1/gems/actionpack-3.1.1/lib/action_view/helpers/date_helper.rb:73:in `distance_of_time_in_words'
    from /usr/lib/ruby/gems/1.9.1/gems/actionpack-3.1.1/lib/action_view/helpers/date_helper.rb:133:in `time_ago_in_words'
    from (irb):2
    from /usr/lib/ruby/gems/1.9.1/gems/railties-3.1.1/lib/rails/commands/console.rb:45:in `start'
    from /usr/lib/ruby/gems/1.9.1/gems/railties-3.1.1/lib/rails/commands/console.rb:8:in `start'
    from /usr/lib/ruby/gems/1.9.1/gems/railties-3.1.1/lib/rails/commands.rb:40:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'irb(main):003:0>
yaroslav commented 12 years ago

Если склонировать и сделать точно так, как вы написали, ошибка повторяется — сейчас посмотрю, что не так

yaroslav commented 12 years ago

А, ну так понятно, почему. Это из-за модуля pluralization I18n, только я не назвал бы это ошибкой и даже непродуманностью :)

Вот что получается, если вставить отладку дедовским способом (puts):

ruby-1.9.3-p0 :001 > I18n.locale = :en
 => :en 
ruby-1.9.3-p0 :002 > ActionController::Base.helpers.time_ago_in_words 2.months.ago
pluralize en, {:one=>"1 month", :other=>"%{count} months"}, 2
key: few
I18n::InvalidPluralizationData: translation data {:one=>"1 month", :other=>"%{count} months"} can not be used with :count => 2
    from /Users/yaroslav/.rvm/gems/ruby-1.9.3-p0/gems/i18n-0.6.0/lib/i18n/backend/pluralization.rb:42:in `pluralize'
    from /Users/yaroslav/.rvm/gems/ruby-1.9.3-p0/gems/i18n-0.6.0/lib/i18n/backend/base.rb:40:in `translate'

И вот как выглядит тот медод

      def pluralize(locale, entry, count)
        return entry unless entry.is_a?(Hash) and count

        puts "pluralize #{locale}, #{entry}, #{count}"

        pluralizer = pluralizer(locale)
        if pluralizer.respond_to?(:call)
          key = count == 0 && entry.has_key?(:zero) ? :zero : pluralizer.call(count)

          puts "key: #{key}"

          raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
          entry[key]
        else
          super
        end
      end

Проще говоря, при включении pluralization он все правила плюрализации ищет в таблице переводов, но при включении модуля fallbacks I18n не будет рапортовать о том, что «перевода» плюрализации для текущей локали нет — вот же он, для дефолтной :ru! В итоге, у вас по фоллбеку берется правило для плюрализации из русской локали, с которым, разумеется, файл стандартных переводов Rails не заведется.

Так что, судя по всему, вы нашли баг в I18n — спасибо за настойчивость :) Цели вас отфутболить у меня не было, если что.

Quick fix: добавьте к себе в переводы что-то вроде этого, должно помочь:

{
  :en => {
    :'i18n' => {
      :plural => {
        :rule => lambda { |n| n == 1 ? :one : :other }
        }
      }
    }
  }
}

Баг я зарепорчу в i18n и скорее всего его пофикшу (думаю, модуль плюрализации просто должен выставлять свой дефолтный перевод для всех локалей). А этот баг пусть повисит открытым пока.

yaroslav commented 12 years ago

https://github.com/svenfuchs/i18n/issues/124

dadittoz commented 12 years ago

Спасибо!

semirenko commented 12 years ago

я так понимаю, что отключение fallback решает проблему?

yaroslav commented 12 years ago

я так понимаю, что отключение fallback решает проблему?

Да, конечно.