module Merit::RankRulesMethods

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.

set_rank accepts:

Public Instance Methods

check_rank_rules() click to toggle source

Not part of merit after_filter. To be called asynchronously: Merit::RankRules.new.check_rank_rules

# File lib/merit/rank_rules_methods.rb, line 31
def check_rank_rules
  defined_rules.each do |scoped_model, level_and_rules|
    level_and_rules.sort.each do |level, rule|
      grant_when_applies(scoped_model, rule, level)
    end
  end
end
defined_rules() click to toggle source

Currently defined rules

# File lib/merit/rank_rules_methods.rb, line 40
def defined_rules
  @defined_rules ||= {}
end
set_rank(*args, &block) click to toggle source

Populates defined_rules hash with following hierarchy:

defined_rules[ModelToRank] = { levels => blocks }
# File lib/merit/rank_rules_methods.rb, line 14
def set_rank(*args, &block)
  options = args.extract_options!

  rule = Rule.new
  rule.block = block
  if options[:level_name].present?
    rule.level_name = "level_#{options[:level_name]}"
  else
    rule.level_name = 'level'
  end

  defined_rules[options[:to]] ||= {}
  defined_rules[options[:to]].merge!(options[:level] => rule)
end

Private Instance Methods

grant_when_applies(scoped_model, rule, level) click to toggle source
# File lib/merit/rank_rules_methods.rb, line 46
def grant_when_applies(scoped_model, rule, level)
  scoped_model.where("#{rule.level_name} < #{level}").each do |object|
    next unless rule.applies?(object)

    object.update_attribute rule.level_name, level
  end
rescue ActiveRecord::StatementInvalid
  str = "Error while granting rankings. Probably you need to add
    #{rule.level_name} column to #{scoped_model.class.name}."
  raise RankAttributeNotDefined, str
end