Module: VoteFu::Concerns::Karmatic::InstanceMethods
- Defined in:
- lib/vote_fu/concerns/karmatic.rb
Instance Method Summary collapse
-
#karma(force: false) ⇒ Integer
Calculate total karma from all sources.
-
#karma_breakdown ⇒ Array<Hash>
Get karma breakdown by source.
-
#karma_for(association) ⇒ Integer
Get karma for a specific source.
-
#karma_level ⇒ String
Get the user's karma level.
-
#karma_level?(level_name) ⇒ Boolean
Check if user has at least a certain karma level.
-
#karma_progress ⇒ Hash
Get progress to next karma level.
-
#recalculate_karma! ⇒ Object
Alias for update_karma_cache.
-
#recent_karma(days: 30) ⇒ Integer
Get karma for last N days only.
-
#update_karma_cache(value = nil) ⇒ Object
Update the karma cache (call periodically or after votes).
Instance Method Details
#karma(force: false) ⇒ Integer
Calculate total karma from all sources
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/vote_fu/concerns/karmatic.rb', line 119 def karma(force: false) return 0 unless self.class.respond_to?(:karma_sources) # Use cached value if available and not forcing recalculation if !force && has_attribute?(:karma_cache) && karma_cache.present? return karma_cache end calculated = self.class.karma_sources.sum do |source| calculate_karma_for(source) end.round # Update cache if column exists update_karma_cache(calculated) if has_attribute?(:karma_cache) && force calculated end |
#karma_breakdown ⇒ Array<Hash>
Get karma breakdown by source
152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/vote_fu/concerns/karmatic.rb', line 152 def karma_breakdown return [] unless self.class.respond_to?(:karma_sources) self.class.karma_sources.map do |source| { source: source[:association], value: calculate_karma_for(source).round, recent: calculate_karma_for(source, since: 30.days.ago).round } end end |
#karma_for(association) ⇒ Integer
Get karma for a specific source
168 169 170 171 172 173 |
# File 'lib/vote_fu/concerns/karmatic.rb', line 168 def karma_for(association) source = self.class.karma_sources.find { |s| s[:association] == association } return 0 unless source calculate_karma_for(source).round end |
#karma_level ⇒ String
Get the user's karma level
178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/vote_fu/concerns/karmatic.rb', line 178 def karma_level return "Unknown" unless self.class.respond_to?(:karma_levels) current_karma = karma level = "Unknown" self.class.karma_levels.sort_by { |k, _| k }.each do |threshold, name| level = name if current_karma >= threshold end level end |
#karma_level?(level_name) ⇒ Boolean
Check if user has at least a certain karma level
245 246 247 248 249 250 251 252 |
# File 'lib/vote_fu/concerns/karmatic.rb', line 245 def karma_level?(level_name) return false unless self.class.respond_to?(:karma_levels) threshold = self.class.karma_levels.key(level_name) return false unless threshold karma >= threshold end |
#karma_progress ⇒ Hash
Get progress to next karma level
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/vote_fu/concerns/karmatic.rb', line 194 def karma_progress return nil unless self.class.respond_to?(:karma_levels) current_karma = karma sorted_levels = self.class.karma_levels.sort_by { |k, _| k } current_threshold = 0 current_level = sorted_levels.first&.last || "Unknown" next_threshold = nil next_level = nil sorted_levels.each_with_index do |(threshold, name), i| if current_karma >= threshold current_threshold = threshold current_level = name # Only set next level if there IS a next level if i < sorted_levels.length - 1 next_data = sorted_levels[i + 1] next_threshold = next_data[0] next_level = next_data[1] else next_threshold = nil next_level = nil end end end if next_threshold.nil? # Already at max level { current_level: current_level, next_level: nil, progress: 100.0, karma_needed: 0 } else range = next_threshold - current_threshold progress_in_range = current_karma - current_threshold { current_level: current_level, next_level: next_level, progress: ((progress_in_range.to_f / range) * 100).round(1), karma_needed: next_threshold - current_karma } end end |
#recalculate_karma! ⇒ Object
Alias for update_karma_cache
263 264 265 266 |
# File 'lib/vote_fu/concerns/karmatic.rb', line 263 def recalculate_karma! update_karma_cache karma(force: true) end |
#recent_karma(days: 30) ⇒ Integer
Get karma for last N days only
141 142 143 144 145 146 147 |
# File 'lib/vote_fu/concerns/karmatic.rb', line 141 def recent_karma(days: 30) return 0 unless self.class.respond_to?(:karma_sources) self.class.karma_sources.sum do |source| calculate_karma_for(source, since: days.days.ago) end.round end |
#update_karma_cache(value = nil) ⇒ Object
Update the karma cache (call periodically or after votes)
255 256 257 258 259 260 |
# File 'lib/vote_fu/concerns/karmatic.rb', line 255 def update_karma_cache(value = nil) return unless has_attribute?(:karma_cache) value ||= self.class.karma_sources.sum { |s| calculate_karma_for(s) }.round update_column(:karma_cache, value) end |