Skip to content
tute edited this page Nov 28, 2012 · 31 revisions

Merit

Frequently Asked Questions

Where is badges data stored?

Badges data is stored in config/initializers/merit.rb using ambry. Ambry is ActiveModel compliant, so it has very few differences to a "normal" ActiveRecord relation.

For instance, calling badges on an object will return an Ambry::Mapper, over which you may call each as with any array, or just convert it to an array with to_a (user.badges.to_a).

Why not storing badges in the database?

If badges are stored in a DB table, and app is deployed without synchronizing the badges data with the server's, it will raise an exception for badge not found, or methods called from merit on nil. Having the app rely on DB entries makes it weak and error prone. badges table would have to be exactly the same for all developers/instances of the app, which is awckward.

Badges tend to be a stable piece of information, and, as the app's stability depend on it, makes much more sense to have that data in code, sourced controlled. If you change merit rules badges you are changing code, and so you change badges data there as well.

ambry is a small library which provides a nice interface to the store of this kind of objects, which are not code but neither harmless data. It also provides validations and nice filtering syntax.

What is each migration/DB-table meant for? On merit internals:

Merit installs three new tables to the app:

  1. merit_actions is meant for internal merit usage. It is the log of "meritable" actions and who triggered them, so that then it can compute per action if points or a badge is to be granted to someone.
  2. sashes defines the Sash model, which has a one-to-one relationship with your "meritable" resources. It has some internally used methods, and it avoids join models.
  3. badges_sashes is a relation table between Badges and "meritable" resources. There's only one join model per app, no matter how many meritable resources it has, thanks to the Sash model. Sash indirection should be invisible for the application, and should not be used.
  4. merit_score_points holds an entry for each point granting/removing, with a num_points integer and an optional log string. They belong to merit_scores which is an indirection between meritable resources and points, meant to hold (still to do) different categories for which a meritable resource may be scored.
  5. It also adds new attributes on each resource: sash_id and level.

How does merit work? (Explanation for developers)

See General workflow.