merit 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. data/Gemfile +5 -0
  2. data/Gemfile.lock +13 -2
  3. data/README.md +72 -53
  4. data/TESTING.txt +7 -2
  5. data/lib/generators/merit/templates/merit.rb +1 -1
  6. data/lib/merit.rb +2 -1
  7. data/lib/merit/controller_extensions.rb +2 -2
  8. data/lib/merit/model_additions.rb +9 -2
  9. data/lib/merit/models/mongo_mapper/merit_action.rb +1 -0
  10. data/lib/merit/models/mongoid/merit_action.rb +13 -0
  11. data/lib/merit/models/mongoid/sash.rb +14 -0
  12. data/lib/merit/rule.rb +4 -2
  13. data/lib/merit/rules_rank.rb +7 -2
  14. data/merit.gemspec +5 -2
  15. data/test/dummy-mongoid/Rakefile +7 -0
  16. data/test/dummy-mongoid/app/controllers/application_controller.rb +7 -0
  17. data/test/dummy-mongoid/app/controllers/comments_controller.rb +90 -0
  18. data/test/dummy-mongoid/app/controllers/registrations_controller.rb +15 -0
  19. data/test/dummy-mongoid/app/controllers/users_controller.rb +67 -0
  20. data/test/dummy-mongoid/app/helpers/application_helper.rb +2 -0
  21. data/test/dummy-mongoid/app/models/comment.rb +17 -0
  22. data/test/dummy-mongoid/app/models/merit/badge_rules.rb +49 -0
  23. data/test/dummy-mongoid/app/models/merit/point_rules.rb +20 -0
  24. data/test/dummy-mongoid/app/models/merit/rank_rules.rb +24 -0
  25. data/test/dummy-mongoid/app/models/user.rb +30 -0
  26. data/test/dummy-mongoid/app/views/comments/_form.html.erb +29 -0
  27. data/test/dummy-mongoid/app/views/comments/edit.html.erb +6 -0
  28. data/test/dummy-mongoid/app/views/comments/index.html.erb +35 -0
  29. data/test/dummy-mongoid/app/views/comments/new.html.erb +5 -0
  30. data/test/dummy-mongoid/app/views/comments/show.html.erb +23 -0
  31. data/test/dummy-mongoid/app/views/layouts/application.html.erb +24 -0
  32. data/test/dummy-mongoid/app/views/users/_form.html.erb +22 -0
  33. data/test/dummy-mongoid/app/views/users/edit.html.erb +6 -0
  34. data/test/dummy-mongoid/app/views/users/index.html.erb +26 -0
  35. data/test/dummy-mongoid/app/views/users/new.html.erb +5 -0
  36. data/test/dummy-mongoid/app/views/users/show.html.erb +18 -0
  37. data/test/dummy-mongoid/config.ru +4 -0
  38. data/test/dummy-mongoid/config/application.rb +22 -0
  39. data/test/dummy-mongoid/config/boot.rb +10 -0
  40. data/test/dummy-mongoid/config/environment.rb +5 -0
  41. data/test/dummy-mongoid/config/environments/development.rb +25 -0
  42. data/test/dummy-mongoid/config/environments/production.rb +49 -0
  43. data/test/dummy-mongoid/config/environments/test.rb +35 -0
  44. data/test/dummy-mongoid/config/initializers/backtrace_silencers.rb +7 -0
  45. data/test/dummy-mongoid/config/initializers/inflections.rb +10 -0
  46. data/test/dummy-mongoid/config/initializers/merit.rb +37 -0
  47. data/test/dummy-mongoid/config/initializers/mime_types.rb +5 -0
  48. data/test/dummy-mongoid/config/initializers/secret_token.rb +7 -0
  49. data/test/dummy-mongoid/config/initializers/session_store.rb +8 -0
  50. data/test/dummy-mongoid/config/locales/en.yml +5 -0
  51. data/test/dummy-mongoid/config/mongoid.yml +14 -0
  52. data/test/dummy-mongoid/config/routes.rb +9 -0
  53. data/test/dummy-mongoid/db/seeds.rb +17 -0
  54. data/test/dummy-mongoid/public/404.html +26 -0
  55. data/test/dummy-mongoid/public/422.html +26 -0
  56. data/test/dummy-mongoid/public/500.html +26 -0
  57. data/test/dummy-mongoid/public/favicon.ico +0 -0
  58. data/test/dummy-mongoid/public/javascripts/application.js +2 -0
  59. data/test/dummy-mongoid/public/javascripts/controls.js +965 -0
  60. data/test/dummy-mongoid/public/javascripts/dragdrop.js +974 -0
  61. data/test/dummy-mongoid/public/javascripts/effects.js +1123 -0
  62. data/test/dummy-mongoid/public/javascripts/prototype.js +6001 -0
  63. data/test/dummy-mongoid/public/javascripts/rails.js +191 -0
  64. data/test/dummy-mongoid/public/stylesheets/.gitkeep +0 -0
  65. data/test/dummy-mongoid/public/stylesheets/scaffold.css +56 -0
  66. data/test/dummy-mongoid/script/rails +6 -0
  67. data/test/dummy/config/initializers/merit.rb +1 -1
  68. data/test/integration/navigation_test.rb +1 -1
  69. data/test/merit_unit_test.rb +3 -0
  70. data/test/test_helper.rb +20 -3
  71. metadata +92 -16
@@ -0,0 +1,90 @@
1
+ class CommentsController < ApplicationController
2
+ # GET /comments
3
+ # GET /comments.xml
4
+ def index
5
+ @comments = Comment.all
6
+
7
+ respond_to do |format|
8
+ format.html # index.html.erb
9
+ format.xml { render :xml => @comments }
10
+ end
11
+ end
12
+
13
+ # GET /comments/1
14
+ # GET /comments/1.xml
15
+ def show
16
+ @comment = Comment.find(params[:id])
17
+
18
+ respond_to do |format|
19
+ format.html # show.html.erb
20
+ format.xml { render :xml => @comment }
21
+ end
22
+ end
23
+
24
+ # GET /comments/new
25
+ # GET /comments/new.xml
26
+ def new
27
+ @comment = Comment.new
28
+
29
+ respond_to do |format|
30
+ format.html # new.html.erb
31
+ format.xml { render :xml => @comment }
32
+ end
33
+ end
34
+
35
+ # GET /comments/1/edit
36
+ def edit
37
+ @comment = Comment.find(params[:id])
38
+ end
39
+
40
+ def vote
41
+ @comment = Comment.find(params[:id])
42
+ @comment.votes += params[:value].to_i
43
+ @comment.save
44
+ redirect_to(comments_url, :notice => 'Vote added!')
45
+ end
46
+
47
+ # POST /comments
48
+ # POST /comments.xml
49
+ def create
50
+ @comment = Comment.new(params[:comment])
51
+
52
+ respond_to do |format|
53
+ if @comment.save
54
+ format.html { redirect_to(@comment, :notice => 'Comment was successfully created.') }
55
+ format.xml { render :xml => @comment, :status => :created, :location => @comment }
56
+ else
57
+ format.html { render "new" }
58
+ format.xml { render :xml => @comment.errors, :status => :unprocessable_entity }
59
+ end
60
+ end
61
+ end
62
+
63
+ # PUT /comments/1
64
+ # PUT /comments/1.xml
65
+ def update
66
+ @comment = Comment.find(params[:id])
67
+
68
+ respond_to do |format|
69
+ if @comment.update_attributes(params[:comment])
70
+ format.html { redirect_to(@comment, :notice => 'Comment was successfully updated.') }
71
+ format.xml { head :ok }
72
+ else
73
+ format.html { render "edit" }
74
+ format.xml { render :xml => @comment.errors, :status => :unprocessable_entity }
75
+ end
76
+ end
77
+ end
78
+
79
+ # DELETE /comments/1
80
+ # DELETE /comments/1.xml
81
+ def destroy
82
+ @comment = Comment.find(params[:id])
83
+ @comment.destroy
84
+
85
+ respond_to do |format|
86
+ format.html { redirect_to(comments_url) }
87
+ format.xml { head :ok }
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,15 @@
1
+ class RegistrationsController < ApplicationController
2
+ def update
3
+ @user = User.find(params[:id])
4
+
5
+ respond_to do |format|
6
+ if @user.update_attributes(params[:user])
7
+ format.html { redirect_to(@user, :notice => 'User was successfully updated.') }
8
+ format.xml { head :ok }
9
+ else
10
+ format.html { render "edit" }
11
+ format.xml { render :xml => @user.errors, :status => :unprocessable_entity }
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,67 @@
1
+ class UsersController < ApplicationController
2
+ # GET /users
3
+ # GET /users.xml
4
+ def index
5
+ @users = User.all
6
+
7
+ respond_to do |format|
8
+ format.html # index.html.erb
9
+ format.xml { render :xml => @users }
10
+ end
11
+ end
12
+
13
+ # GET /users/1
14
+ # GET /users/1.xml
15
+ def show
16
+ @user = User.find(params[:id])
17
+
18
+ respond_to do |format|
19
+ format.html # show.html.erb
20
+ format.xml { render :xml => @user }
21
+ end
22
+ end
23
+
24
+ # GET /users/new
25
+ # GET /users/new.xml
26
+ def new
27
+ @user = User.new
28
+
29
+ respond_to do |format|
30
+ format.html # new.html.erb
31
+ format.xml { render :xml => @user }
32
+ end
33
+ end
34
+
35
+ # GET /users/1/edit
36
+ def edit
37
+ @user = User.find(params[:id])
38
+ end
39
+
40
+ # POST /users
41
+ # POST /users.xml
42
+ def create
43
+ @user = User.new(params[:user])
44
+
45
+ respond_to do |format|
46
+ if @user.save
47
+ format.html { redirect_to(@user, :notice => 'User was successfully created.') }
48
+ format.xml { render :xml => @user, :status => :created, :location => @user }
49
+ else
50
+ format.html { render "new" }
51
+ format.xml { render :xml => @user.errors, :status => :unprocessable_entity }
52
+ end
53
+ end
54
+ end
55
+
56
+ # DELETE /users/1
57
+ # DELETE /users/1.xml
58
+ def destroy
59
+ @user = User.find(params[:id])
60
+ @user.destroy
61
+
62
+ respond_to do |format|
63
+ format.html { redirect_to(users_url) }
64
+ format.xml { head :ok }
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,17 @@
1
+ class Comment
2
+ include Mongoid::Document
3
+ include Mongoid::Timestamps
4
+ belongs_to :user
5
+
6
+ field :name
7
+ field :comment
8
+ field :votes, :type => Integer, :default => 0
9
+
10
+ attr_accessible :name, :comment, :user_id, :votes
11
+
12
+ validates :name, :comment, :user_id, :presence => true
13
+
14
+ def self.find_by_id(id)
15
+ where(:_id => id).first
16
+ end
17
+ end
@@ -0,0 +1,49 @@
1
+ # +grant_on+ accepts:
2
+ # * Nothing (always grants)
3
+ # * A block which evaluates to boolean (recieves the object as parameter)
4
+ # * A block with a hash composed of methods to run on the target object with
5
+ # expected values (+:votes => 5+ for instance).
6
+ #
7
+ # +grant_on+ can have a +:to+ method name, which called over the target object
8
+ # should retrieve the object to badge (could be +:user+, +:self+, +:follower+,
9
+ # etc). If it's not defined merit will apply the badge to the user who
10
+ # triggered the action (:action_user by default). If it's :itself, it badges
11
+ # the created object (new user for instance).
12
+ #
13
+ # The :temporary option indicates that if the condition doesn't hold but the
14
+ # badge is granted, then it's removed. It's false by default (badges are kept
15
+ # forever).
16
+
17
+ module Merit
18
+ class BadgeRules
19
+ include Merit::BadgeRulesMethods
20
+
21
+ def initialize
22
+ # If it creates user, grant badge
23
+ # Should be "current_user" after registration for badge to be granted.
24
+ # Example rule with block with no parameters
25
+ grant_on 'users#create', :badge => 'just-registered', :to => :itself do
26
+ Date.today > 1.year.ago.to_date
27
+ end
28
+
29
+ # Example rule for multiple badge granting
30
+ grant_on 'users#index', :badge => 'gossip', :multiple => true
31
+
32
+ # If it has 10 comments, grant commenter-10 badge
33
+ grant_on 'comments#create', :badge => 'commenter', :level => 10 do |comment|
34
+ comment.user.comments.count >= 10
35
+ end
36
+
37
+ # If it has at least 10 votes, grant relevant-commenter badge
38
+ grant_on 'comments#vote', :badge => 'relevant-commenter', :to => :user do |comment|
39
+ comment.votes >= 10
40
+ end
41
+
42
+ # Changes his name by one wider than 4 chars (arbitrary ruby code and custom model_name)
43
+ # This badge is temporary (user may lose it)
44
+ grant_on 'registrations#update', :badge => 'autobiographer', :temporary => true, :model_name => 'User' do |user|
45
+ user.name.length > 4
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,20 @@
1
+ # Points are a simple integer value which are given to "meritable" resources
2
+ # according to rules in +app/models/merit_point_rules.rb+. They are given on
3
+ # actions-triggered.
4
+
5
+ module Merit
6
+ class PointRules
7
+ include Merit::PointRulesMethods
8
+
9
+ def initialize
10
+ score 5, :to => :user, :on => [
11
+ 'comments#vote'
12
+ ]
13
+
14
+ score 20, :on => [
15
+ 'comments#create',
16
+ 'registrations#update'
17
+ ]
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ # 5 stars is a common ranking use case. They are not given at specified
2
+ # actions like badges, you should define a cron job to test if ranks are to be
3
+ # granted.
4
+ #
5
+ # +set_rank+ accepts:
6
+ # * :+level+ ranking level (greater is better)
7
+ # * :+to+ model or scope to check if new rankings apply
8
+ # * :+level_name+ attribute name (default is empty and results in 'level'
9
+ # attribute, if set it's appended like 'level_#{level_name}')
10
+
11
+ module Merit
12
+ class RankRules
13
+ include Merit::RankRulesMethods
14
+
15
+ def initialize
16
+ # i stars for i chars name
17
+ (1..5).each do |i|
18
+ set_rank :level => i, :to => User do |user|
19
+ user.name.length == i
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ class User
2
+ include Mongoid::Document
3
+ include Mongoid::Timestamps
4
+
5
+ has_merit
6
+
7
+ field :name
8
+
9
+ has_many :comments
10
+
11
+ attr_accessible :name
12
+
13
+ def self.find_by_id(id)
14
+ where(:_id => id).first
15
+ end
16
+
17
+ def show_badges
18
+ create_sash_if_none
19
+ badges_uniq = Badge.find_by_id(sash.badge_ids)
20
+ badges_uniq.collect{|b| "#{b.name.capitalize}#{badge_status(b)}" }.join(', ')
21
+ end
22
+
23
+ def badge_status(badge)
24
+ status = []
25
+ count = badges.select{|b| b.name == badge.name }.count
26
+ status << "level: #{badge.level}" if badge.level
27
+ status << "x#{count}" if count > 1
28
+ status.present? ? " (#{status.join(', ')})" : ''
29
+ end
30
+ end
@@ -0,0 +1,29 @@
1
+ <%= form_for(@comment) do |f| %>
2
+ <% if @comment.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(@comment.errors.count, "error") %> prohibited this comment from being saved:</h2>
5
+
6
+ <ul>
7
+ <% @comment.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= f.label :name %><br />
16
+ <%= f.text_field :name %>
17
+ </div>
18
+ <div class="field">
19
+ <%= f.label :comment %><br />
20
+ <%= f.text_area :comment %>
21
+ </div>
22
+ <div class="field">
23
+ <%= f.label :user_id %><br />
24
+ <%= f.text_field :user_id %>
25
+ </div>
26
+ <div class="actions">
27
+ <%= f.submit %>
28
+ </div>
29
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing comment</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Show', @comment %> |
6
+ <%= link_to 'Back', comments_path %>
@@ -0,0 +1,35 @@
1
+ <h1>Listing comments</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Name</th>
6
+ <th>Comment</th>
7
+ <th>User</th>
8
+ <th>Votes</th>
9
+ <th>Vote up!</th>
10
+ <th></th>
11
+ <th></th>
12
+ <th></th>
13
+ </tr>
14
+
15
+ <% @comments.each do |comment| %>
16
+ <tr id="c_<%= comment.id %>">
17
+ <td><%= comment.name %></td>
18
+ <td><%= comment.comment %></td>
19
+ <td><%= comment.user_id %></td>
20
+ <td><%= comment.votes %></td>
21
+ <td>
22
+ <% (1..5).each do |i| %>
23
+ <%= link_to "#{i}", "/comments/#{comment.id}/vote/#{i}" %>
24
+ <% end %>
25
+ </td>
26
+ <td><%= link_to 'Show', comment %></td>
27
+ <td><%= link_to 'Edit', edit_comment_path(comment) %></td>
28
+ <td><%= link_to 'Destroy', comment, :confirm => 'Are you sure?', :method => :delete %></td>
29
+ </tr>
30
+ <% end %>
31
+ </table>
32
+
33
+ <br />
34
+
35
+ <%= link_to 'New Comment', new_comment_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New comment</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Back', comments_path %>
@@ -0,0 +1,23 @@
1
+ <p>
2
+ <b>Name:</b>
3
+ <%= @comment.name %>
4
+ </p>
5
+
6
+ <p>
7
+ <b>Comment:</b>
8
+ <%= @comment.comment %>
9
+ </p>
10
+
11
+ <p>
12
+ <b>User:</b>
13
+ <%= @comment.user_id %>
14
+ </p>
15
+
16
+ <p>
17
+ <b>Vote:</b>
18
+ <%= @comment.votes %>
19
+ </p>
20
+
21
+
22
+ <%= link_to 'Edit', edit_comment_path(@comment) %> |
23
+ <%= link_to 'Back', comments_path %>
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Merit Dummy app</title>
6
+ <%= stylesheet_link_tag :all %>
7
+ <%= javascript_include_tag :all %>
8
+ <%= csrf_meta_tag %>
9
+ </head>
10
+ <body>
11
+ <h1><%= link_to 'Dummy app', '/' %></h1>
12
+
13
+ <% flash.each do |name, msg| %>
14
+ <%= content_tag :p, msg, :class => (name == 'error' ? 'error' : 'notice') %>
15
+ <% end %>
16
+
17
+ <%= yield %>
18
+
19
+ <ul>
20
+ <li><%= link_to 'Users', users_url %></li>
21
+ <li><%= link_to 'Comments', comments_url %></li>
22
+ </ul>
23
+ </body>
24
+ </html>