merit 1.2.3 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- merit (1.2.3)
4
+ merit (1.3.0)
5
5
  ambry (~> 0.3.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -143,5 +143,4 @@ end
143
143
 
144
144
  # To-do list
145
145
 
146
- * Improve model_additions with http://blog.8thlight.com/josh-cheek/2012/02/03/modules-called-they-want-their-integrity-back.html
147
146
  * Should namespace Badge, BadgesSash and Sash into Merit module.
@@ -1,5 +1,24 @@
1
1
  # Upgrading
2
2
 
3
+ ## to 1.3.0
4
+
5
+ Adds two methods meant to display a leaderboard.
6
+
7
+ * `Badge#last_granted(options = {})`. Accepts options:
8
+ * `:since_date` (`1.month.ago` by default)
9
+ * `:limit` (10 by default).
10
+
11
+ It lists last 10 badge grants in the last month, unless you change query
12
+ parameters.
13
+
14
+ * `Merit::Score.top_scored(options = {})`. Accepts options:
15
+ * `:table_name` (`users` by default)
16
+ * `:since_date` (`1.month.ago` by default)
17
+ * `:limit` (10 by default).
18
+
19
+ It lists top 10 scored objects in the last month, unless you change query
20
+ parameters.
21
+
3
22
  ## to 1.2.0
4
23
 
5
24
  * `Badge#grant_to(meritable_object)` no longer exists. Use
@@ -31,4 +31,11 @@ class Badge
31
31
  end
32
32
  badge
33
33
  end
34
+
35
+ # Last badges granted
36
+ def self.last_granted(options = {})
37
+ options[:since_date] ||= 1.month.ago
38
+ options[:limit] ||= 10
39
+ BadgesSash.last_granted(options)
40
+ end
34
41
  end
@@ -14,9 +14,6 @@ require "merit/models/#{Merit.orm}/merit/action"
14
14
  # Rules relate to merit_actions by action name ('controller#action' string)
15
15
  module Merit
16
16
  class Action
17
- attr_accessible :user_id, :action_method, :action_value, :had_errors,
18
- :target_model, :target_id, :processed, :log
19
-
20
17
  def self.check_unprocessed
21
18
  where(:processed => false).map &:check_all_rules
22
19
  end
@@ -57,9 +57,7 @@ module Merit
57
57
  include Merit::ControllerExtensions
58
58
  rescue NameError => e
59
59
  # Trap NameError if installing/generating files
60
- if !(e.to_s =~ /uninitialized constant Merit::BadgeRules/)
61
- raise e
62
- end
60
+ raise e unless e.to_s =~ /uninitialized constant Merit::BadgeRules/
63
61
  end
64
62
  end
65
63
  end
@@ -9,21 +9,20 @@ module Merit
9
9
  # https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/1079-belongs_to-dependent-destroy-should-destroy-self-before-assocation
10
10
  belongs_to :sash
11
11
 
12
- merit_orm_specific_config
13
-
14
- merit_delegate_methods_to_sash
15
- merit_sash_initializer
12
+ _merit_orm_specific_config
13
+ _merit_delegate_methods_to_sash
14
+ _merit_sash_initializer
16
15
  end
17
16
 
18
17
  # Delegate methods from meritable models to their sash
19
- def merit_delegate_methods_to_sash
18
+ def _merit_delegate_methods_to_sash
20
19
  methods = %w(badge_ids badges points
21
20
  add_badge rm_badge
22
21
  add_points substract_points)
23
22
  methods.each { |method| delegate method, to: :_sash }
24
23
  end
25
24
 
26
- def merit_orm_specific_config
25
+ def _merit_orm_specific_config
27
26
  if Merit.orm == :mongo_mapper
28
27
  plugin Merit
29
28
  key :sash_id, String
@@ -43,7 +42,7 @@ module Merit
43
42
  # From Rails 3.2 we can override association methods to do so
44
43
  # transparently, but merit supports Rails ~> 3.0.0. See:
45
44
  # http://blog.hasmanythrough.com/2012/1/20/modularized-association-methods-in-rails-3-2
46
- def merit_sash_initializer
45
+ def _merit_sash_initializer
47
46
  define_method(:_sash) do
48
47
  if sash.nil?
49
48
  self.update_attribute :sash_id, Sash.create.id
@@ -1,6 +1,14 @@
1
1
  class BadgesSash < ActiveRecord::Base
2
2
  belongs_to :sash
3
3
 
4
+ def self.last_granted(options = {})
5
+ options[:since_date] ||= 1.month.ago
6
+ options[:limit] ||= 10
7
+ where("created_at > '#{options[:since_date]}'").
8
+ limit(options[:limit]).
9
+ map(&:badge)
10
+ end
11
+
4
12
  def badge
5
13
  Badge.find(badge_id)
6
14
  end
@@ -1,5 +1,8 @@
1
1
  module Merit
2
2
  class Action < ActiveRecord::Base
3
3
  self.table_name = :merit_actions
4
+
5
+ attr_accessible :user_id, :action_method, :action_value, :had_errors,
6
+ :target_model, :target_id, :processed, :log
4
7
  end
5
8
  end
@@ -4,6 +4,40 @@ module Merit
4
4
  belongs_to :sash
5
5
  has_many :score_points, :dependent => :destroy, :class_name => 'Merit::Score::Point'
6
6
 
7
+ # Meant to display a leaderboard. Accepts options :table_name (users by
8
+ # default), :since_date (1.month.ago by default) and :limit (10 by
9
+ # default).
10
+ #
11
+ # It lists top 10 scored objects in the last month, unless you change
12
+ # query parameters.
13
+ def self.top_scored(options = {})
14
+ options[:table_name] ||= :users
15
+ options[:since_date] ||= 1.month.ago
16
+ options[:limit] ||= 10
17
+
18
+ alias_id_column = "#{options[:table_name].to_s.singularize}_id"
19
+ if options[:table_name] == :sashes
20
+ sash_id_column = "#{options[:table_name]}.id"
21
+ else
22
+ sash_id_column = "#{options[:table_name]}.sash_id"
23
+ end
24
+
25
+ # MeritableModel – Sash –< Scores –< ScorePoints
26
+ sql_query = <<SQL
27
+ SELECT
28
+ #{options[:table_name]}.id AS #{alias_id_column},
29
+ SUM(num_points) as sum_points
30
+ FROM #{options[:table_name]}
31
+ LEFT JOIN merit_scores ON merit_scores.sash_id = #{sash_id_column}
32
+ LEFT JOIN merit_score_points ON merit_score_points.score_id = merit_scores.id
33
+ WHERE merit_score_points.created_at > '#{options[:since_date]}'
34
+ GROUP BY merit_scores.sash_id
35
+ ORDER BY sum_points DESC
36
+ LIMIT #{options[:limit]}
37
+ SQL
38
+ ActiveRecord::Base.connection.execute(sql_query)
39
+ end
40
+
7
41
  def points
8
42
  score_points.group(:score_id).sum(:num_points).values.first || 0
9
43
  end
@@ -4,7 +4,7 @@ Gem::Specification.new do |s|
4
4
  s.description = "Manage badges, points and rankings (reputation) of resources in a Rails application."
5
5
  s.homepage = "http://github.com/tute/merit"
6
6
  s.files = `git ls-files`.split("\n").reject{|f| f =~ /^\./ }
7
- s.version = '1.2.3'
7
+ s.version = '1.3.0'
8
8
  s.authors = ["Tute Costa"]
9
9
  s.email = 'tutecosta@gmail.com'
10
10
  s.add_dependency 'ambry', '~> 0.3.0'
@@ -48,6 +48,35 @@ class MeritUnitTest < ActiveSupport::TestCase
48
48
  assert badge_sash.notified_user
49
49
  end
50
50
 
51
+ test "Badge#last_granted returns recently granted badges" do
52
+ sash = Sash.create
53
+ badge = Badge.create(id: 20, name: 'test-badge-21')
54
+ sash.add_badge badge.id
55
+ BadgesSash.last.update_attribute :created_at, 1.day.ago
56
+ sash.add_badge badge.id
57
+ BadgesSash.last.update_attribute :created_at, 8.days.ago
58
+ sash.add_badge badge.id
59
+ BadgesSash.last.update_attribute :created_at, 15.days.ago
60
+
61
+ assert_equal Badge.last_granted(since_date: Time.now), []
62
+ assert_equal Badge.last_granted(since_date: 1.week.ago), [badge]
63
+ assert_equal Badge.last_granted(since_date: 2.weeks.ago).count, 2
64
+ assert_equal Badge.last_granted(since_date: 2.weeks.ago, limit: 1), [badge]
65
+ end
66
+
67
+ test "Merit::Score.top_scored returns scores leaderboard" do
68
+ sash_1 = Sash.create
69
+ sash_1.add_points(10); sash_1.add_points(10)
70
+ sash_2 = Sash.create
71
+ sash_2.add_points(5); sash_2.add_points(5)
72
+
73
+ assert_equal Merit::Score.top_scored(table_name: :sashes),
74
+ [{"sash_id"=>1, "sum_points"=>20, 0=>1, 1=>20},
75
+ {"sash_id"=>2, "sum_points"=>10, 0=>2, 1=>10}]
76
+ assert_equal Merit::Score.top_scored(table_name: :sashes, limit: 1),
77
+ [{"sash_id"=>1, "sum_points"=>20, 0=>1, 1=>20}]
78
+ end
79
+
51
80
  test 'unknown ranking should raise merit exception' do
52
81
  class WeirdRankRules
53
82
  include Merit::RankRulesMethods
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: merit
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-03 00:00:00.000000000 Z
12
+ date: 2013-01-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ambry