Skip to content

Commit 3acf87e

Browse files
authored
Merge pull request rails#52426 from shouichi/raise-on-missing-translations
Change ActiveModel human_attribute_name to raise an error
2 parents 042f2d7 + f6c0a35 commit 3acf87e

File tree

6 files changed

+61
-2
lines changed

6 files changed

+61
-2
lines changed

activemodel/CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
* Add a load hook `active_model_translation` for `ActiveModel::Translation`.
2+
3+
*Shouichi Kamiya*
4+
5+
* Add `raise_on_missing_translations` option to `ActiveModel::Translation`.
6+
When the option is set, `human_attribute_name` raises an error if a translation of the given attribute is missing.
7+
8+
```ruby
9+
# ActiveModel::Translation.raise_on_missing_translations = false
10+
Post.human_attribute_name("title")
11+
=> "Title"
12+
13+
# ActiveModel::Translation.raise_on_missing_translations = true
14+
Post.human_attribute_name("title")
15+
=> Translation missing. Options considered were: (I18n::MissingTranslationData)
16+
- en.activerecord.attributes.post.title
17+
- en.attributes.title
18+
19+
raise exception.respond_to?(:to_exception) ? exception.to_exception : exception
20+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
21+
```
22+
23+
*Shouichi Kamiya*
24+
125
* Introduce `ActiveModel::AttributeAssignment#attribute_writer_missing`
226

327
Provide instances with an opportunity to gracefully handle assigning to an

activemodel/lib/active_model/translation.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ module ActiveModel
2222
module Translation
2323
include ActiveModel::Naming
2424

25+
singleton_class.attr_accessor :raise_on_missing_translations
26+
2527
# Returns the +i18n_scope+ for the class. Override if you want custom lookup.
2628
def i18n_scope
2729
:activemodel
@@ -60,13 +62,17 @@ def human_attribute_name(attribute, options = {})
6062
end
6163
end
6264

65+
raise_on_missing = options.fetch(:raise, Translation.raise_on_missing_translations)
66+
6367
defaults << :"attributes.#{attribute}"
6468
defaults << options[:default] if options[:default]
65-
defaults << MISSING_TRANSLATION
69+
defaults << MISSING_TRANSLATION unless raise_on_missing
6670

67-
translation = I18n.translate(defaults.shift, count: 1, **options, default: defaults)
71+
translation = I18n.translate(defaults.shift, count: 1, raise: raise_on_missing, **options, default: defaults)
6872
translation = attribute.humanize if translation == MISSING_TRANSLATION
6973
translation
7074
end
7175
end
76+
77+
ActiveSupport.run_load_hooks(:active_model_translation, Translation)
7278
end

activemodel/test/cases/translation_test.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# frozen_string_literal: true
22

3+
require "active_support/core_ext/object/with"
34
require "cases/helper"
45
require "models/person"
56

@@ -126,4 +127,12 @@ def test_human_attribute_name_does_not_modify_options
126127
Person.human_attribute_name("gender", options)
127128
assert_equal({ default: "Cool gender" }, options)
128129
end
130+
131+
def test_raise_on_missing_translations
132+
ActiveModel::Translation.with(raise_on_missing_translations: true) do
133+
assert_raises I18n::MissingTranslationData do
134+
Person.human_attribute_name("name")
135+
end
136+
end
137+
end
129138
end

activesupport/lib/active_support/i18n_railtie.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ def self.setup_raise_on_missing_translations_config(app)
8383
ActionView::Helpers::TranslationHelper.raise_on_missing_translations = app.config.i18n.raise_on_missing_translations
8484
end
8585

86+
ActiveSupport.on_load(:active_model_translation) do
87+
ActiveModel::Translation.raise_on_missing_translations = app.config.i18n.raise_on_missing_translations
88+
end
89+
8690
if app.config.i18n.raise_on_missing_translations &&
8791
I18n.exception_handler.is_a?(I18n::ExceptionHandler) # Only override the i18n gem's default exception handler.
8892

guides/source/configuring.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3741,6 +3741,7 @@ These are the load hooks you can use in your own code. To hook into the initiali
37413741
| `ActiveJob::Base` | `active_job` |
37423742
| `ActiveJob::TestCase` | `active_job_test_case` |
37433743
| `ActiveModel::Model` | `active_model` |
3744+
| `ActiveModel::Translation` | `active_model_translation` |
37443745
| `ActiveRecord::Base` | `active_record` |
37453746
| `ActiveRecord::TestFixtures` | `active_record_fixtures` |
37463747
| `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter` | `active_record_postgresqladapter` |

railties/test/application/configuration_test.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4633,6 +4633,21 @@ def view_test
46334633
assert_includes last_response.body, "rescued missing translation error from view"
46344634
end
46354635

4636+
test "raise_on_missing_translations affects human_attribute_name in model" do
4637+
add_to_config "config.i18n.raise_on_missing_translations = true"
4638+
4639+
app_file "app/models/post.rb", <<-RUBY
4640+
class Post < ActiveRecord::Base
4641+
end
4642+
RUBY
4643+
4644+
app "development"
4645+
4646+
assert_raises I18n::MissingTranslationData do
4647+
Post.human_attribute_name("title")
4648+
end
4649+
end
4650+
46364651
test "dom testing uses the HTML5 parser in new apps if it is supported" do
46374652
app "development"
46384653
expected = defined?(Nokogiri::HTML5) ? :html5 : :html4

0 commit comments

Comments
 (0)