Skip to content

Commit

Permalink
Support translations for ActiveRecord models
Browse files Browse the repository at this point in the history
Problem:

Developers are unable to display their ActiveRecord classes in the UI
by any other name than the titleized class name.

For example,
if a team is building an admin dashboard that will be used in Russian,
they may have ActiveRecord models with English names, that need to be
translated before they're displayed in the UI.

Solution:

Rails has support for [translating ActiveRecord Models][1],
which relies on defining I18n translations
under the `activerecord.models` namespace.

Rails expects translations in the form:

```yaml
en:
  activerecord:
    models:
      user:
        one: Customer
        other: Customers
```

The separate `one` and `other` keys allow Rails to display
the correct plural or singular form of the word,
depending on the context.

We've used Rails' built-in `Foo.model_name.human` method
to correctly pull the translations out of I18n,
with sane fallbacks if the translation is not defined.

[1]: http://guides.rubyonrails.org/i18n.html#translations-for-active-record-models
  • Loading branch information
c-lliope committed Dec 7, 2015
1 parent 956fa3f commit c75b572
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

* [#251] [FEATURE] Raise a helpful error when an attribute is missing from
`ATTRIBUTE_TYPES`
* [#298] [FEATURE] Support ActiveRecord model I18n translations
* [#231] [UI] Fix layout issue on show page where a long label next to an empty
value would cause following fields on the page to be mis-aligned.
* [#259] [BUGFIX] Make installation generator more robust
Expand Down
12 changes: 12 additions & 0 deletions app/helpers/administrate/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,17 @@ def render_field(field, locals = {})
locals.merge!(field: field)
render locals: locals, partial: field.to_partial_path
end

def display_resource_name(resource_name)
resource_name.
to_s.
classify.
constantize.
model_name.
human(
count: 0,
default: resource_name.to_s.pluralize.titleize,
)
end
end
end
2 changes: 1 addition & 1 deletion app/views/administrate/application/_sidebar.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ as defined by the DashboardManifest.
<% DashboardManifest::DASHBOARDS.each do |resource| %>
<li>
<%= link_to(
resource.to_s.titleize,
display_resource_name(resource),
[Administrate::NAMESPACE, resource],
class: "sidebar__link sidebar__link--#{nav_link_state(resource)}"
) %>
Expand Down
4 changes: 3 additions & 1 deletion app/views/administrate/application/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ It renders the `_table` partial to display details about the resources.
[1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Table
%>

<% content_for(:title) { page.resource_name.pluralize.titleize } %>
<% content_for(:title) do %>
<%= display_resource_name(page.resource_name) %>
<% end %>

<% content_for(:search) do %>
<form class="search">
Expand Down
21 changes: 21 additions & 0 deletions spec/features/sidebar_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,25 @@

expect(active_link.text).to eq "Customers"
end

it "displays translated name of model" do
translations = {
activerecord: {
models: {
customer: {
one: "User",
other: "Users",
},
},
},
}

with_translations(:en, translations) do
visit admin_customers_path

sidebar = find(".sidebar__list")
expect(sidebar).to have_link("Users")
expect(page).to have_header("Users")
end
end
end
44 changes: 44 additions & 0 deletions spec/helpers/administrate/application_helper_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require "rails_helper"

RSpec.describe Administrate::ApplicationHelper do
describe "#display_resource_name" do
it "defaults to the plural of the model name" do
displayed = display_resource_name(:customer)

expect(displayed).to eq("Customers")
end

it "handles string arguments" do
displayed = display_resource_name("customer")

expect(displayed).to eq("Customers")
end

it "handles plural arguments" do
displayed = display_resource_name(:customers)

expect(displayed).to eq("Customers")
end

context "when translations are defined" do
it "uses the plural of the defined translation" do
translations = {
activerecord: {
models: {
customer: {
one: "User",
other: "Users",
},
},
},
}

with_translations(:en, translations) do
displayed = display_resource_name(:customer)

expect(displayed).to eq("Users")
end
end
end
end
end
11 changes: 11 additions & 0 deletions spec/support/i18n.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
RSpec.configure do |config|
config.include AbstractController::Translation

def with_translations(locale, translations)
original_backend = I18n.backend

I18n.backend = I18n::Backend::KeyValue.new({}, true)
I18n.backend.store_translations(locale, translations)

yield
ensure
I18n.backend = original_backend
end
end

0 comments on commit c75b572

Please sign in to comment.