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.
- data/Gemfile +5 -0
- data/Gemfile.lock +13 -2
- data/README.md +72 -53
- data/TESTING.txt +7 -2
- data/lib/generators/merit/templates/merit.rb +1 -1
- data/lib/merit.rb +2 -1
- data/lib/merit/controller_extensions.rb +2 -2
- data/lib/merit/model_additions.rb +9 -2
- data/lib/merit/models/mongo_mapper/merit_action.rb +1 -0
- data/lib/merit/models/mongoid/merit_action.rb +13 -0
- data/lib/merit/models/mongoid/sash.rb +14 -0
- data/lib/merit/rule.rb +4 -2
- data/lib/merit/rules_rank.rb +7 -2
- data/merit.gemspec +5 -2
- data/test/dummy-mongoid/Rakefile +7 -0
- data/test/dummy-mongoid/app/controllers/application_controller.rb +7 -0
- data/test/dummy-mongoid/app/controllers/comments_controller.rb +90 -0
- data/test/dummy-mongoid/app/controllers/registrations_controller.rb +15 -0
- data/test/dummy-mongoid/app/controllers/users_controller.rb +67 -0
- data/test/dummy-mongoid/app/helpers/application_helper.rb +2 -0
- data/test/dummy-mongoid/app/models/comment.rb +17 -0
- data/test/dummy-mongoid/app/models/merit/badge_rules.rb +49 -0
- data/test/dummy-mongoid/app/models/merit/point_rules.rb +20 -0
- data/test/dummy-mongoid/app/models/merit/rank_rules.rb +24 -0
- data/test/dummy-mongoid/app/models/user.rb +30 -0
- data/test/dummy-mongoid/app/views/comments/_form.html.erb +29 -0
- data/test/dummy-mongoid/app/views/comments/edit.html.erb +6 -0
- data/test/dummy-mongoid/app/views/comments/index.html.erb +35 -0
- data/test/dummy-mongoid/app/views/comments/new.html.erb +5 -0
- data/test/dummy-mongoid/app/views/comments/show.html.erb +23 -0
- data/test/dummy-mongoid/app/views/layouts/application.html.erb +24 -0
- data/test/dummy-mongoid/app/views/users/_form.html.erb +22 -0
- data/test/dummy-mongoid/app/views/users/edit.html.erb +6 -0
- data/test/dummy-mongoid/app/views/users/index.html.erb +26 -0
- data/test/dummy-mongoid/app/views/users/new.html.erb +5 -0
- data/test/dummy-mongoid/app/views/users/show.html.erb +18 -0
- data/test/dummy-mongoid/config.ru +4 -0
- data/test/dummy-mongoid/config/application.rb +22 -0
- data/test/dummy-mongoid/config/boot.rb +10 -0
- data/test/dummy-mongoid/config/environment.rb +5 -0
- data/test/dummy-mongoid/config/environments/development.rb +25 -0
- data/test/dummy-mongoid/config/environments/production.rb +49 -0
- data/test/dummy-mongoid/config/environments/test.rb +35 -0
- data/test/dummy-mongoid/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy-mongoid/config/initializers/inflections.rb +10 -0
- data/test/dummy-mongoid/config/initializers/merit.rb +37 -0
- data/test/dummy-mongoid/config/initializers/mime_types.rb +5 -0
- data/test/dummy-mongoid/config/initializers/secret_token.rb +7 -0
- data/test/dummy-mongoid/config/initializers/session_store.rb +8 -0
- data/test/dummy-mongoid/config/locales/en.yml +5 -0
- data/test/dummy-mongoid/config/mongoid.yml +14 -0
- data/test/dummy-mongoid/config/routes.rb +9 -0
- data/test/dummy-mongoid/db/seeds.rb +17 -0
- data/test/dummy-mongoid/public/404.html +26 -0
- data/test/dummy-mongoid/public/422.html +26 -0
- data/test/dummy-mongoid/public/500.html +26 -0
- data/test/dummy-mongoid/public/favicon.ico +0 -0
- data/test/dummy-mongoid/public/javascripts/application.js +2 -0
- data/test/dummy-mongoid/public/javascripts/controls.js +965 -0
- data/test/dummy-mongoid/public/javascripts/dragdrop.js +974 -0
- data/test/dummy-mongoid/public/javascripts/effects.js +1123 -0
- data/test/dummy-mongoid/public/javascripts/prototype.js +6001 -0
- data/test/dummy-mongoid/public/javascripts/rails.js +191 -0
- data/test/dummy-mongoid/public/stylesheets/.gitkeep +0 -0
- data/test/dummy-mongoid/public/stylesheets/scaffold.css +56 -0
- data/test/dummy-mongoid/script/rails +6 -0
- data/test/dummy/config/initializers/merit.rb +1 -1
- data/test/integration/navigation_test.rb +1 -1
- data/test/merit_unit_test.rb +3 -0
- data/test/test_helper.rb +20 -3
- 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,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,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,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>
|