Merit Gem: Reputation rules (badges, points and rankings) for Rails applications
- ActiveRecord or Mongoid
gem 'merit'to your
rails g merit:install
rails g merit MODEL_NAME
- Depending on your ORM
- ActiveRecord: Run
- Mongoid: Set
config.orm = :mongoidin
- ActiveRecord: Run
- Define badges you will use in
- Configure reputation rules for your application in
Defining badge rules
You may give badges to any resource on your application if some condition
holds. Badges may have levels, and may be temporary. Define rules on
'controller#action'string (similar to Rails routes)
:badgefor badge name
:levelfor badge level
:tomethod name over target_object which obtains object to badge
:model_name(string) define controller's name if it differs from the model (like
:multiple(boolean) badge may be granted multiple times
:temporary(boolean) if the receiver had the badge but the condition doesn't hold anymore, remove it.
falseby default (badges are kept forever).
- empty (always grants)
- a block which evaluates to boolean (recieves target object as parameter)
- a block with a hash composed of methods to run on the target object with expected values
grant_on 'comments#vote', :badge => 'relevant-commenter', :to => :user do |comment| comment.votes.count == 5 end grant_on ['users#create', 'users#update'], :badge => 'autobiographer', :temporary => true do |user| user.name.present? && user.address.present? end
You may also grant badges "by hand":
Defining point rules
Points are a simple integer value which are given to "meritable" resources.
They are given on actions-triggered, either to the action user or to the
method(s) defined in the
:to option. Define rules on
score 10, :on => [ 'users#update' ] score 20, :on => [ 'comments#create', 'photos#create' ]
:to method(s) work as in badge rules: they are sent to the target_object.
In the following example, after a review gets created both
review.reviewed are granted 15 points:
score 15, :on => 'reviews#create', :to => [:reviewer, :reviewed]
Defining rank rules
5 stars is a common ranking use case. They are not given at specified actions like badges, you should define a cron job to test if ranks are to be granted.
Define rules on
:levelranking level (greater is better)
:tomodel or scope to check if new rankings apply
:level_nameattribute name (default is empty and results in '
level' attribute, if set it's appended like '
Check for rules on a rake task executed in background like:
task :cron => :environment do Merit::RankRules.new.check_rank_rules end
set_rank :level => 2, :to => Commiter.active do |commiter| commiter.branches > 1 && commiter.followers >= 10 end set_rank :level => 3, :to => Commiter.active do |commiter| commiter.branches > 2 && commiter.followers >= 20 end
- add an error handler for inexistent badges.
- rails g merit MODEL_NAME shouldn't create general migrations again.
- Abstract User (rule.rb#51 for instance) into a Merit option.
- Should namespace app/models into Merit module.
- rescue ActiveRecord::... should depend on ORM used
- :value parameter (for star voting for example) should be configurable (depends on params[:value] on the controller).
- Make fixtures for integration testing (now creating objects on test file!).