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

Close
Introduction
============

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
environments.

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.

Example
=======

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

		PAYMENT_TYPES = SuperMap.new(
				[: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 }]
			)

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

	end

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
method.

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.new( :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

	PAYMENT_TYPES.labeled_values

to get the form directly suitable to pass options to f.select 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

	end

Now a whole lot of new methods comes into play:

	p = Payment.new( :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

Thanks
======

Many thanks go to Stefan Nothegger and Sharewise project
(http://www.sharewise.com), where the original idea and large parts of the code
originate from.

Recent activity

starware

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 ProjectModifiedEvent.java.
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.