Bitbucket is a code hosting site with unlimited public and private repositories. We're also free for small teams!


SuperMap is a two-way, multi-purpose ordered hash with some additional
capabilities (additional attributes, translations). It is meant to be used with
Rails, but it doesn't depend on them, so someone might find it useful in other

Ever had an enumerable field in a model that would map to a select box in a
form? Wanted some nice way to operate it as symbol in the code, integer in
database and label in views? That's where SuperMap comes into play.


Let's say there is a Payment model with two enumerable fields:
- payment_type: Cash In, Cash Out, Bonus, Commission
- payment_method: Paypal, Bank Transfer, Manual

We define 2 SuperMaps:

	class Payment

				[:cash_in, 1, { :label => "Cash In", :tax => 0.01 }],
				[:cash_out, 2, { :label => "Cash Out", :tax => 0.02 }],
				[:bonus, 123, { :label => "Bonus Payment", :tax => 0.03 }],
				[:commission, 384728, { :tax => 0.01 }]

				[:paypal, 1, { :label => "Paid via Paypal", :favorite => true }],
				[:bank_transfer, 2],
				[:manual, 3],
				:translation_scope => "activerecord.models.payment.payment_methods"


PAYMENT_TYPES defines options for payment_type field. First parameter is a key
that should be used to access this element instead of using value, which comes
second as integer (and is possibly stored in database). Note that value might be
totally random, it just needs be unique across elements. Some labels are set
explicitly, for other options key.titleize will be used implicitly. We also
defined a custom attribute :tax, which can be accessed using SuperMap#attribute

PAYMENT_METHODS define translation_scope, which means labels will be present in
translations file (I18n - note that it's totally optional). :paypal will have
custom label, which overrides translations.

We can than use those SuperMaps to handle attributes for Payment instances:
	payment = :payment_method => 1 )
	payment.payment_type = PAYMENT_TYPES[:cash_out]			# Set to 2
	label = PAYMENT_TYPES.label( payment.payment_type ) # "Cash Out"
	label = PAYMENT_TYPES.label( :bonus )								# "Bonus Payment"
	value = PAYMENT_METHODS[payment.payment_method]			# 1
	tax = PAYMENT_TYPES.attribute( payment.payment_type, :tax ) # 0.02
	tax = PAYMENT_TYPES.attribute( :bonus, :tax ) # 0.03

We can also use


to get the form directly suitable to pass options to helper method.

To make things even simpler, we can use super_mapped_attr:

	class Payment
		... # SuperMaps declarations

		super_mapped_attr :payment_type, PAYMENT_TYPES
		super_mapped_attr :payment_method, PAYMENT_METHODS


Now a whole lot of new methods comes into play:

	p = :payment_method => 1 )
	p.payment_method_label                      # "Paid via Paypal"
	p.payment_method_key												# :paypal
	p.payment_method_attr( :favorite )					# true
	p.payment_method_key = :manual
	p.payment_method														# 3


Many thanks go to Stefan Nothegger and Sharewise project
(, where the original idea and large parts of the code
originate from.

Recent activity


Commits by starware were pushed to starware/super_map

66aee34 - Removed variable caching as it wreaked havoc with I18n and locale changing
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.