Skip to content

Instantly share code, notes, and snippets.

@amiel
Created November 4, 2011 19:55
Show Gist options
  • Select an option

  • Save amiel/1340319 to your computer and use it in GitHub Desktop.

Select an option

Save amiel/1340319 to your computer and use it in GitHub Desktop.
Using I18n and Draper to Render Database Attributes Blog Post
# Show a user-friendly version of our identifier
Status: <%= current_user.status.humanize %>
# Now we need to customize some of them, use I18n
Status: <%= t current_user.status, default: current_user.status.humanize %>
# But that's polluting our I18n namespace
Status: <%= t :"user.status.#{ current_user.status }", default: current_user.status.humanize %>
# Ok, this is getting out of hand, lets refactor this to the model
Status: <%= current_user.status_string %>
# This breaks down when you need to render the select field to edit this user
<%= form.input :status, collection: User::STATUSES.map { |s| [User.new(status: s).status_string, s] } %>
# So, how 'bout a helper
Status: <%= humanize_with_i18n current_user.status, %(user status) %>
# Not too bad
<%= form.input :status, collection: User::STATUSES.map { |s| [humanize_with_i18n(s), s] } %>
# Ah, this is a bit better
<%= form.input :status, collection: user_roles_for_select %>
class User < ActiveRecord::Base
# ...
def status_string
I18n.t status, scope: %w(user status), default: status.humanize
end
def another_thing_string
I18n.t ...
# ...
end
# Or something like:
module UserHelper
def humanize_with_i18n(string, scope = [])
I18n.t string, scope: scope, default: string.humanize
end
# The method prefix tells me that this should be in an object
# But it doesn't belong in our model, does it?
def user_roles_for_select
User::STATUSES.map { |s| [humanize_with_i18n(s), s] }
end
end
class UserDecorator < ApplicationDecorator
decorates :user
def status
# self.model gives us the User
self.class.humanize_with_i18n(:status, model.status)
end
# This could be moved to ApplicationDecorator (or ApplicationHelper),
# but is shown here for simplicity.
def self.humanize_with_i18n(attribute, value)
I18n.t value, scope: ['user', attribute], default: value
end
def self.status_options
User::STATUSES.map { |s| [humanize_with_i18n(:status, s), s] }
end
end
Status: <%= current_user.decorator.status %>
<%= form.input :status, collection: UserDecorator.status_options %>
class UserDecorator < ApplicationDecorator
decorates :user
humanizes :status
def self.status_options
options_for_select_with_i18n :status, model_class::STATUS_OPTIONS
end
end
Status: <%= current_user.status %>
<%= form.input :status, collection: UserDecorator.status_options %>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment