joshmcarthur/Latter — pull request #47 by bretman (2012-09-05 07:58:22+00:00)
Title: Final badge implementation

Right.

Here is the badge implementation,

Features include:

- Create badges which are assigned based on a ransack condition. Badge.award_condition. The condition is applied to Player.games but ransack fields can traverse the object hierarchy to test other models.

- The ability to specify a historical date range for award_conditions (see below)

- Players are checked for badge eligibility on game save.

- A badge may be assigned multiple times to a player unless Badge.allow_duplicates is set to false.

- A badge lasts indefinitely unless Badge.expire_in_days is > 0 in which case it automatically expires.

The badge expiry is implemented by calculating an absolute datetime when a badge is awarded. This is assigned to Award.expiry. Awards are excluded by a default_scope using lambda to check Award.expiry against the current DateTime.

Award_conditions that include created_at_gt in the ransack search are a special case. The value of created_at_gt is considered an offset in hours prior to the current date. This condition is substituted to a literal DateTime prior to completing the ransack search. This allows, for example, searches for the number of games in the last week by including ":created_at_gt => 168" hours.

Award_rule_count allows greater than and less than comparisons. A positive count means to test for a number of matching search results that is greater than the number. A negative count means to test for a number of matching search results that is less than the number. Award_rule_count = 0 means award the badge for any search results being returned.

Example badge:

"Frequent Flyer" - awarded if the player has more than 5 games in a day. The badge expires in 1 day and can only be awarded once each day.

Badge:
:name => "Frequent Flyer"
:description => "Had more than 5 games today"
:award_condition => "award_rule: {:created_at_gt=>24}"
:award_rule_count => 5
:allow_duplicates => false
:expire_in_days = 1

I've included tests for these features and have tried most scenarios, but we need some examples to check all is working as planned.

Feedback appreciated.

Cheers,

Bret

p.s. most recent latter master has been pulled and merged into the add-badges-brr branch.