Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Model classes are loaded before I18n is set when running tests.

#5522

Model classes should be always loaded after full framework configuration.


# config/locales/en.yml 
en:
  hello: "Hello world"

# config/locales/pl.yml 
pl:
  hello: "Witaj swiecie"

# app/models/my_model.rb
class MyModel < ActiveRecord::Base
  raise I18n.available_locales.inspect # just to demonstrate the bug
end

# test/unit/my_model_test.rb 
require 'test_helper'

class MyModelTest < ActiveSupport::TestCase
  test "the truth" { MyModel }
end

As you can see there are 2 files with 2 different locales and my class depends on them ex.:

class MyModel < ActiveRecord::Base
  I18n.available_locales.each do |locale|
    define_method("name_#{locale}") { ... do something ...} # This is what I actually do.
  end
end

When running from the console

> rails cosnole
Loading development environment (Rails 3.0.0)
ruby-1.9.2-head > MyModel
RuntimeError: [:en, :pl] 
    from /home/rupert/test/r3koma0/app/models/my_model.rb:3:in `<class:MyModel>'
    from /home/rupert/test/r3koma0/app/models/my_model.rb:1:in `<top (required)>'

everything is fine. Both locales ([:en, :pl]) are found and I'm happy.

However when running test:

ruby -Ilib:test test/unit/my_model_test.rb 

/home/rupert/test/r3koma0/app/models/my_model.rb:3:in `<class:MyModel>': [:en] (RuntimeError)
    from /home/rupert/test/r3koma0/app/models/my_model.rb:1:in `<top (required)>'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:239:in `require'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:239:in `block in require'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:227:in `load_dependency'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:239:in `require'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:346:in `require_or_load'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:300:in `depend_on'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:216:in `require_dependency'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/railties-3.0.0/lib/rails/engine.rb:138:in `block (2 levels) in eager_load!'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/railties-3.0.0/lib/rails/engine.rb:137:in `each'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/railties-3.0.0/lib/rails/engine.rb:137:in `block in eager_load!'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/railties-3.0.0/lib/rails/engine.rb:135:in `each'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/railties-3.0.0/lib/rails/engine.rb:135:in `eager_load!'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/railties-3.0.0/lib/rails/application.rb:108:in `eager_load!'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/railties-3.0.0/lib/rails/application/finisher.rb:41:in `block in <module:Finisher>'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/railties-3.0.0/lib/rails/initializable.rb:25:in `instance_exec'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/railties-3.0.0/lib/rails/initializable.rb:25:in `run'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/railties-3.0.0/lib/rails/initializable.rb:50:in `block in run_initializers'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/railties-3.0.0/lib/rails/initializable.rb:49:in `each'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/railties-3.0.0/lib/rails/initializable.rb:49:in `run_initializers'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/railties-3.0.0/lib/rails/application.rb:134:in `initialize!'
    from /home/rupert/.rvm/gems/ruby-1.9.2-head/gems/railties-3.0.0/lib/rails/application.rb:77:in `method_missing'
    from /home/rupert/test/r3koma0/config/environment.rb:5:in `<top (required)>'
    from <internal:lib/rubygems/custom_require>:29:in `require'
    from <internal:lib/rubygems/custom_require>:29:in `require'
    from /home/rupert/test/r3koma0/test/test_helper.rb:2:in `<top (required)>'
    from <internal:lib/rubygems/custom_require>:29:in `require'
    from <internal:lib/rubygems/custom_require>:29:in `require'
    from test/unit/my_model_test.rb:1:in `<main>

As you can see during the test something is loaded in a different order and I18n is not set yet, thus only one locale ([:en]) is found. Maybe eager_load! is called to early before loading everything that is related to I18n ?

Changing the files to :

# test/unit/my_model_test.rb 
require 'test_helper'
class MyModelTest < ActiveSupport::TestCase
  test "the truth" {raise I18n.available_locales.inspect}
end

# app/models/my_model.rb 
class MyModel < ActiveRecord::Base
end

shows that after everything is loaded in test environment, locales are again properly returned:

ruby -Ilib:test test/unit/my_model_test.rb 
Loaded suite test/unit/my_model_test
Started
E
Finished in 0.018779 seconds.

  1) Error:
test_the_truth(MyModelTest):
RuntimeError: [:en, :pl]
    test/unit/my_model_test.rb:6:in `block in <class:MyModelTest>'

Reported by Robert Pankowecki · September 1st, 2010 @ 04:59 PM

State: duplicate
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Franco Catena
    Franco Catena
    • Tag changed from testing environment, eager_loading, i18n, rails3, test to eager_loading, i18n, rails3

    I have the same problem, the i18n configuration is not loaded consistently across environmets. I create a patch that fix this, is for the master branch, but can be easily implemented in the other 3.X branches (only 3 lines of code).

    I hope this helps anyone with the same problem.

    Regards.

    November 18th, 2010 @ 01:00 PM

  2. Franco Catena
    Franco Catena
    • Tag changed from eager_loading, i18n, rails3 to testing environment, eager_loading, i18n, rails3

    Sorry, I accidentally delete the testing environment tag.

    November 18th, 2010 @ 01:04 PM

  3. Robert Pankowecki
    Robert Pankowecki

    It is nice to have a fix and it would be even better to have a test for this so it will not change accidentally in the future.

    November 18th, 2010 @ 01:10 PM

  4. Franco Catena
    Franco Catena

    Yes, I am working on the tests and an improvement of this patch, because only works when you have cache_classes = true (I just notice that, so is better avoid using it for now).

    November 18th, 2010 @ 09:13 PM

  5. Robert Pankowecki
    Robert Pankowecki

    Thanks for your time and paying attention to this bug. I really appreciate that.

    November 18th, 2010 @ 11:01 PM

  6. Franco Catena
    Franco Catena

    OK, there I go again.

    • Short version: the patch fix this issue

    • Long version: the configuration of the i18n railtie was in the after_initialize callback of the Rails configuration hooks, they are called after the classes eager load proccess. In the current schema of callbacks this can not be fixed, so I add the after_configuration method to the Rails configuration hooks (just when finisher starts). I make 2 new tests in the i18n initializer tests for this and include the new hook in the hook's tests.

    Is a messy explanation, I know =).

    Regards.

    November 23rd, 2010 @ 04:10 PM

  7. Robert Pankowecki
    Robert Pankowecki

    I wish I could test it but master branch is failing due to "Rack::Session::Abstract::SessionHash" when running rails console.

    November 23rd, 2010 @ 05:02 PM

  8. Robert Pankowecki
    Robert Pankowecki
    • Tag changed from testing environment, eager_loading, i18n, rails3 to testing environment, eager_loading, i18n, patch, rails3

    November 23rd, 2010 @ 05:02 PM

  9. Franco Catena
    Franco Catena

    Robert, I make one patch for the 3.0 stable branch (because this must be fixed in 3.0 too), I hope you can try this.

    November 23rd, 2010 @ 05:27 PM

  10. Robert Pankowecki
    Robert Pankowecki

    I checked the patch for 3.0-stable and it works ok for the case described in this ticket.
    Thank you!

    November 24th, 2010 @ 08:41 AM

  11. Robert Pankowecki
    Robert Pankowecki
    • Tag changed from testing environment, eager_loading, i18n, patch, rails3 to testing environment, cache_classes, eager_loading, i18n, patch, rails3

    November 24th, 2010 @ 08:49 AM

  12. lewy313
    lewy313

    I checked that patch today at work, and it works for me ;)

    November 24th, 2010 @ 08:51 AM

  13. Franco Catena
    Franco Catena
    • Tag changed from testing environment, cache_classes, eager_loading, i18n, patch, rails3 to testing environment, cache_classes, eager_loading, i18n, patch, rails3, railties, verified

    OK, thank you for the confirmations, I will update the tags to add verified and railties.

    November 24th, 2010 @ 11:51 AM

  14. Franco Catena
    Franco Catena
    • Tag changed from testing environment, cache_classes, eager_loading, i18n, patch, rails3, railties, verified to testing environment, cache_classes, eager_loading, i18n, patch, rails3, railties

    Ops I don't read well, It sais 3 people, tag verified removed

    November 24th, 2010 @ 11:53 AM

  15. Miłosz Jerkiewicz
  16. Franco Catena
    Franco Catena
    • Tag changed from testing environment, cache_classes, eager_loading, i18n, patch, rails3, railties to testing environment, cache_classes, eager_loading, i18n, patch, rails3, railties, verified

    November 25th, 2010 @ 11:38 AM

  17. tbh
    tbh

    Is #6353 I18n load path needs to be setup before eager loading about the same issue as this ticket? In case one wants to coordinate the patches...

    February 7th, 2011 @ 01:03 PM

  18. José Valim
    José Valim
    • State changed from new to duplicate
    • Importance changed from to Low

    February 7th, 2011 @ 01:09 PM

  19. Franco Catena
    Franco Catena

    It is a shame, I do not know what is wrong with this path, why the one in #6353 I18n load path needs to be setup before eager loading was accepted and this is not.

    February 7th, 2011 @ 01:19 PM

  20. José Valim
    José Valim

    Sorry Franco, but it was not intentional. Somehow, #6353 I18n load path needs to be setup before eager loading found his way to a Rails Core first. :( I just got to know about this one after someone dropped a comment on #6353 I18n load path needs to be setup before eager loading.

    February 7th, 2011 @ 01:36 PM

  21. Franco Catena
    Franco Catena

    OK José, no problem, thank you for you concern.

    February 7th, 2011 @ 01:54 PM