Issues with custom error message translations
elcommie opened this issue · comments
We have a model class in rails with the following validation:
validates :items, length: {
minimum: 1, message: I18n.t('items.one_required')
}
This works fine in version 5.0.1, but in 5.0.2 there's a translation missing: en.items.one_required
in the errors collection. Not sure why factory_bot would affect the i18n class but it appears to.
There was a bug in 5.0.1 that was causing the factory_bot_rails reloader to watch the project root in some cases. We fixed that in 5.0.2. This probably has something to do with that fix. This is definitely not expected behavior!
- What file is your translation in?
- Is the I18n reloader watching that file? (You can look at
Rails.application.reloaders
in the console. For me the I18n reloader is the second one in that list.) (You might also look around in https://github.com/rails/rails/blob/master/activesupport/lib/active_support/i18n_railtie.rb#L41-L74 for clues.)
I will try my best to reproduce this. Please share whatever details you can.
Thanks!
It's in the standard config/locales/en.yml
file and I see that file near the bottom of the reloaders as you'd expect.
Interestingly, I tried loading factory_bot in console and creating a record there and it worked. But in rspec
it fails. Also, I tried just creating a new model that wasn't as complex as mine (my production model inherits from two different other models, uses mixins and a number of other things built up over the years) and that one worked too. Very odd. I'll see if I can narrow down the scenario that triggers this
@composerinteralia I had the same issue come up and I think I narrowed it down to this change, though it might actually be the one mentioned above(#331 ). I'm not sure how to recommend a fix 😅 but maybe some more information:
It appears the new change is causing the suite to load_definitions
before the globalization yml files are loaded. Interestingly enough, I was able to get tests successfully passing by putting a binding.pry
in a factory (in which I was able to verify that the translations are not being loaded before the factory definitions are loaded), and calling FactoryBot.reload
in the console, which in a hacky way loaded the I18n translations, allowing the test to succeed since the translations were then defined.
Hope this helps 😄
Also ran into the same error, any news on when this might be fixed?
Would one of you be able to provide a sample application that reproduces the error? That would make this much easier to debug.
@composerinteralia Interestingly, I replicated the relevant code in a rails new
application, but can't seem to reproduce the error. Not sure if that helps at all.
@composerinteralia I'm running into this as well with this application: https://github.com/codeforamerica/ohana-api
Here is an example failing spec: https://github.com/codeforamerica/ohana-api/blob/master/spec/api/patch_organization_spec.rb#L76
Here is the presence validation with custom localized error message: https://github.com/codeforamerica/ohana-api/blob/master/app/models/organization.rb#L17
And here is the custom message defined in config/locales/en.yml
:
https://github.com/codeforamerica/ohana-api/blob/master/config/locales/en.yml#L342
Hey, are there any updates on the issue? I am experiencing the same bug in our project.
No updates that I know of. I haven't been able to reproduce the error in the ohana-api application because I haven't been able to get it running. I think I need either a simpler application that reproduces the error, or some help getting ohana-api set up.
@composerinteralia Ok, I've found a way to reproduce it in a new rails app.
https://github.com/zuchmanski/factory-bot-rails-failing-example
To reproduce please clone the repo, bundle install
, rake db:schema:load
and run rspec --backtrace spec/example_spec.rb
.
I've found out that it only happens if you try to read translation during class loading inside the factory:
class Post < ApplicationRecord
HELLO = I18n.t('hello')
end
FactoryBot.define do
factory :post do
title { 'Message' }
# This loads a Post class, fails since translations are not loaded yet.
# Comment this line and spec passes.
Post::HELLO
end
end
Full diff from empty rails app: https://github.com/zuchmanski/factory-bot-rails-failing-example/commit/2953068207b22eeb08dc00c495addb4c2dcddce0
Hi, I have the same issue with a translation present in a model.
I reproduced it really quickly with this code:
class Model
REASONS = I18n.t("enumerize.reason")
end
Whereas I had no problem before updating factory_bot_rails from 5.0.1 to 5.0.2, now I have this:
I18n::MissingTranslationData (translation missing: en.enumerize.reason)
Is there anything I can do to help you? Have you been able to reproduce the behavior with my repo?
I can try working on it if you could point me the changes, files that you suspect broke the code loading logic.
I am experiencing a similar case
code:
class Model
validates :foreign_key_id, presence: { message: I18n.t('path.to.locale') }
end
test:
it do
is_expected.to validate_presence_of(:foreign_key_id).with_message(I18n.t('path.to.locale'))
end
error:
Expected Model to validate that :foreign_key_id cannot be
empty/falsy, producing a custom validation error on failure, but this
could not be proved.
After setting :foreign_key_id to ‹nil›, the matcher expected the
Model to be invalid and to produce the validation
error "Locale translation" on :foreign_key_id. The record was indeed
invalid, but it produced these validation errors instead:
* foreign_key_id: ["<span class=\"translation_missing\"
title=\"translation missing: en.path.to.locale\">Path To Locale</span>"]
I have an idea about how to fix this. I will work on it a bit today and then either make a PR or post here what I have learned so far.
Not quite ready to merge, since I had some trouble with testing, but it would be helpful if somebody that has encountered this problem can confirm that the fix in #343 works for you.
I tried it out on the app @zuchmanski provided and it seems to have done the trick.
@composerinteralia on my setup it returned the following error:
An error occurred while loading rails_helper.
Failure/Error: require File.expand_path('../config/environment', __dir__)
NoMethodError:
undefined method `reloader' for #<Test::Application:0x00007fdd0202a0f8>
Did you mean? reloaders
# ./config/environment.rb:4:in `<top (required)>'
# ./spec/rails_helper.rb:4:in `<top (required)>'
Thanks for trying it out! I am also seeing that error on CI for certain versions. It seems there is more work to be done here. What version of Rails are you on?
That project is on rails 4.2.11.1
Not quite ready to merge, since I had some trouble with testing, but it would be helpful if somebody that has encountered this problem can confirm that the fix in #343 works for you.
@composerinteralia I confirm that the fix works in our projects! Thanks!
@composerinteralia I confirm it fixes the issue in ohana-api. Thanks!
@composerinteralia #347 works for us (did not test #343, though)