- Add
gem 'merit'
to yourGemfile
- Run
rails g merit:install
- Run
rails g merit MODEL_NAME
(e.g.user
) - Run
rake db:migrate
- Define badges you will use in
config/initializers/merit.rb
- Configure reputation rules for your application in
app/models/merit/*
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
app/models/merit/badge_rules.rb
:
grant_on
accepts:
'controller#action'
string (similar to Rails routes):badge
for badge name:level
for badge level:to
method name over target_object which obtains object to badge:model_name
(string) define controller's name if it differs from the model (likeRegistrationsController
forUser
model).: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.false
by default (badges are kept forever).&block
- 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
# app/models/merit/badge_rules.rb
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
# Check granted badges
current_user.badges # Returns an array of badges
# Grant or remove manually
current_user.add_badge(badge.id)
current_user.rm_badge(badge.id)
Points are given to "meritable" resources on actions-triggered, either to the
action user or to the method(s) defined in the :to
option. Define rules on
app/models/merit/point_rules.rb
:
score
accepts:
:on
action as string or array of strings (similar to Rails routes):to
method(s) to send to the target_object (who should be scored?)&block
- empty (always scores)
- a block which evaluates to boolean (recieves target object as parameter)
# app/models/merit/point_rules.rb
score 10, :to => :post_creator, :on => 'comments#create' do |comment|
comment.title.present?
end
score 20, :on => [
'comments#create',
'photos#create'
]
score 15, :on => 'reviews#create', :to => [:reviewer, :reviewed]
# Check awarded points
current_user.points # Returns an integer
# Score manually
current_user.add_points(20, 'Optional log message')
current_user.substract_points(10)
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 app/models/merit/rank_rules.rb
:
set_rank
accepts:
:level
ranking level (greater is better):to
model or scope to check if new rankings apply:level_name
attribute name (default is empty and results in 'level
' attribute, if set it's appended like 'level_#{level_name}
')
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
- Improve model_additions with http://blog.8thlight.com/josh-cheek/2012/02/03/modules-called-they-want-their-integrity-back.html
- Should namespace Badge, BadgesSash and Sash into Merit module.