qalam_merit 4.0.4
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +358 -0
- data/RELEASING.md +16 -0
- data/Rakefile +44 -0
- data/TESTING.txt +12 -0
- data/config/locales/en.yml +5 -0
- data/lib/merit.rb +95 -0
- data/lib/merit/badge_rules_methods.rb +30 -0
- data/lib/merit/base_target_finder.rb +31 -0
- data/lib/merit/class_methods.rb +41 -0
- data/lib/merit/controller_extensions.rb +71 -0
- data/lib/merit/generators/active_record/install_generator.rb +40 -0
- data/lib/merit/generators/active_record/merit_generator.rb +25 -0
- data/lib/merit/generators/active_record/remove_generator.rb +30 -0
- data/lib/merit/generators/active_record/templates/add_merit_fields_to_model.erb +7 -0
- data/lib/merit/generators/active_record/templates/create_badges_sashes.erb +14 -0
- data/lib/merit/generators/active_record/templates/create_merit_actions.erb +16 -0
- data/lib/merit/generators/active_record/templates/create_merit_activity_logs.erb +12 -0
- data/lib/merit/generators/active_record/templates/create_merit_badges.erb +17 -0
- data/lib/merit/generators/active_record/templates/create_sashes.erb +8 -0
- data/lib/merit/generators/active_record/templates/create_scores_and_points.erb +16 -0
- data/lib/merit/generators/active_record/templates/remove_merit_fields_from_model.erb +7 -0
- data/lib/merit/generators/active_record/templates/remove_merit_tables.erb +12 -0
- data/lib/merit/generators/install_generator.rb +30 -0
- data/lib/merit/generators/merit_generator.rb +33 -0
- data/lib/merit/generators/remove_generator.rb +23 -0
- data/lib/merit/generators/templates/badge.erb +69 -0
- data/lib/merit/generators/templates/merit.erb +18 -0
- data/lib/merit/generators/templates/merit_badge_rules.erb +50 -0
- data/lib/merit/generators/templates/merit_point_rules.erb +31 -0
- data/lib/merit/generators/templates/merit_rank_rules.erb +32 -0
- data/lib/merit/generators/templates/qalam_badge_sash.erb +20 -0
- data/lib/merit/generators/templates/qalam_sash.erb +14 -0
- data/lib/merit/judge.rb +102 -0
- data/lib/merit/models/action_concern.rb +50 -0
- data/lib/merit/models/active_record/action.rb +11 -0
- data/lib/merit/models/active_record/activity_log.rb +11 -0
- data/lib/merit/models/active_record/badges_sash.rb +13 -0
- data/lib/merit/models/active_record/sash.rb +32 -0
- data/lib/merit/models/active_record/score.rb +25 -0
- data/lib/merit/models/badges_sash_concern.rb +13 -0
- data/lib/merit/models/base/badges_sash.rb +15 -0
- data/lib/merit/models/base/sash.rb +55 -0
- data/lib/merit/models/sash_concern.rb +53 -0
- data/lib/merit/point_rules_methods.rb +33 -0
- data/lib/merit/rank_rules_methods.rb +58 -0
- data/lib/merit/reputation_change_observer.rb +19 -0
- data/lib/merit/rule.rb +35 -0
- data/lib/merit/rules_matcher.rb +24 -0
- data/lib/merit/sash_finder.rb +15 -0
- data/lib/merit/target_finder.rb +43 -0
- data/qalam_merit.gemspec +23 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/controllers/admin/users_controller.rb +9 -0
- data/test/dummy/app/controllers/api/comments_controller.rb +5 -0
- data/test/dummy/app/controllers/api/users_controller.rb +5 -0
- data/test/dummy/app/controllers/application_controller.rb +7 -0
- data/test/dummy/app/controllers/comments_controller.rb +56 -0
- data/test/dummy/app/controllers/registrations_controller.rb +21 -0
- data/test/dummy/app/controllers/users_controller.rb +38 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/address.rb +3 -0
- data/test/dummy/app/models/comment.rb +13 -0
- data/test/dummy/app/models/dummy_observer.rb +3 -0
- data/test/dummy/app/models/merit/badge_rules.rb +66 -0
- data/test/dummy/app/models/merit/point_rules.rb +44 -0
- data/test/dummy/app/models/merit/rank_rules.rb +24 -0
- data/test/dummy/app/models/user.rb +23 -0
- data/test/dummy/app/views/admin/users/index.html.erb +26 -0
- data/test/dummy/app/views/comments/_form.html.erb +29 -0
- data/test/dummy/app/views/comments/edit.html.erb +6 -0
- data/test/dummy/app/views/comments/index.html.erb +35 -0
- data/test/dummy/app/views/comments/new.html.erb +5 -0
- data/test/dummy/app/views/comments/show.html.erb +23 -0
- data/test/dummy/app/views/layouts/application.html.erb +24 -0
- data/test/dummy/app/views/users/_form.html.erb +22 -0
- data/test/dummy/app/views/users/edit.html.erb +6 -0
- data/test/dummy/app/views/users/index.html.erb +27 -0
- data/test/dummy/app/views/users/new.html.erb +5 -0
- data/test/dummy/app/views/users/show.html.erb +18 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +26 -0
- data/test/dummy/config/application_api_only.rb +28 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +22 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environment_api_only.rb +7 -0
- data/test/dummy/config/environments/development.rb +24 -0
- data/test/dummy/config/environments/production.rb +51 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/merit.rb +47 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/new_framework_defaults.rb +3 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/mongoid.yml +13 -0
- data/test/dummy/config/routes.rb +16 -0
- data/test/dummy/db/migrate/20110421191249_create_users.rb +12 -0
- data/test/dummy/db/migrate/20110421191250_create_comments.rb +16 -0
- data/test/dummy/db/migrate/20120318022220_add_fields_to_users.rb +11 -0
- data/test/dummy/db/migrate/20130321082817_add_fields_to_comments.rb +11 -0
- data/test/dummy/db/migrate/20130329224406_create_merit_actions.rb +18 -0
- data/test/dummy/db/migrate/20130329224407_create_merit_activity_logs.rb +15 -0
- data/test/dummy/db/migrate/20130329224408_create_sashes.rb +11 -0
- data/test/dummy/db/migrate/20130329224409_create_badges_sashes.rb +16 -0
- data/test/dummy/db/migrate/20130329224410_create_scores_and_points.rb +20 -0
- data/test/dummy/db/migrate/20140211144001_create_addresses.rb +11 -0
- data/test/dummy/db/migrate/20140819133931_add_target_data_to_merit_actions.rb +5 -0
- data/test/dummy/db/schema.rb +89 -0
- data/test/dummy/db/seeds.rb +19 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/rails.js +404 -0
- data/test/dummy/public/stylesheets/.gitkeep +0 -0
- data/test/dummy/public/stylesheets/scaffold.css +56 -0
- data/test/dummy/script/rails +6 -0
- data/test/integration/navigation_test.rb +332 -0
- data/test/support/integration_case.rb +5 -0
- data/test/test_helper.rb +40 -0
- data/test/unit/action_test.rb +12 -0
- data/test/unit/base_target_finder_test.rb +64 -0
- data/test/unit/merit_unit_test.rb +33 -0
- data/test/unit/rule_unit_test.rb +57 -0
- data/test/unit/rules_matcher_test.rb +37 -0
- data/test/unit/sash_finder_test.rb +27 -0
- data/test/unit/sash_test.rb +104 -0
- data/test/unit/score_test.rb +13 -0
- data/test/unit/target_finder_test.rb +98 -0
- metadata +360 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module Merit
|
|
2
|
+
# 5 stars is a common ranking use case. They are not given at specified
|
|
3
|
+
# actions like badges, you should define a cron job to test if ranks are to
|
|
4
|
+
# be granted.
|
|
5
|
+
#
|
|
6
|
+
# +set_rank+ accepts:
|
|
7
|
+
# * :+level+ ranking level (greater is better)
|
|
8
|
+
# * :+to+ model or scope to check if new rankings apply
|
|
9
|
+
# * :+level_name+ attribute name (default is empty and results in 'level'
|
|
10
|
+
# attribute, if set it's appended like 'level_#{level_name}')
|
|
11
|
+
module RankRulesMethods
|
|
12
|
+
# Populates +defined_rules+ hash with following hierarchy:
|
|
13
|
+
# defined_rules[ModelToRank] = { levels => blocks }
|
|
14
|
+
def set_rank(*args, &block)
|
|
15
|
+
options = args.extract_options!
|
|
16
|
+
|
|
17
|
+
rule = Rule.new
|
|
18
|
+
rule.block = block
|
|
19
|
+
if options[:level_name].present?
|
|
20
|
+
rule.level_name = "level_#{options[:level_name]}"
|
|
21
|
+
else
|
|
22
|
+
rule.level_name = 'level'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
defined_rules[options[:to]] ||= {}
|
|
26
|
+
defined_rules[options[:to]].merge!(options[:level] => rule)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Not part of merit after_filter. To be called asynchronously:
|
|
30
|
+
# Merit::RankRules.new.check_rank_rules
|
|
31
|
+
def check_rank_rules
|
|
32
|
+
defined_rules.each do |scoped_model, level_and_rules|
|
|
33
|
+
level_and_rules.sort.each do |level, rule|
|
|
34
|
+
grant_when_applies(scoped_model, rule, level)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Currently defined rules
|
|
40
|
+
def defined_rules
|
|
41
|
+
@defined_rules ||= {}
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def grant_when_applies(scoped_model, rule, level)
|
|
47
|
+
scoped_model.where("#{rule.level_name} < #{level}").each do |object|
|
|
48
|
+
next unless rule.applies?(object)
|
|
49
|
+
|
|
50
|
+
object.update_attribute rule.level_name, level
|
|
51
|
+
end
|
|
52
|
+
rescue ActiveRecord::StatementInvalid
|
|
53
|
+
str = "Error while granting rankings. Probably you need to add
|
|
54
|
+
#{rule.level_name} column to #{scoped_model.class.name}."
|
|
55
|
+
raise RankAttributeNotDefined, str
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Merit
|
|
2
|
+
class ReputationChangeObserver
|
|
3
|
+
def update(changed_data)
|
|
4
|
+
ActivityLog.create(
|
|
5
|
+
description: changed_data[:description],
|
|
6
|
+
related_change: related_change(changed_data),
|
|
7
|
+
action_id: changed_data[:merit_action_id]
|
|
8
|
+
)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def related_change(data)
|
|
14
|
+
if data[:merit_object].respond_to?(:activity_logs)
|
|
15
|
+
data[:merit_object]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/merit/rule.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Merit
|
|
2
|
+
# Rules has a badge name and level, a target to badge, a conditions block
|
|
3
|
+
# and a temporary option.
|
|
4
|
+
# Could split this class between badges and rankings functionality
|
|
5
|
+
class Rule
|
|
6
|
+
attr_accessor :badge_id, :badge_name, :level, :to, :model_name, :level_name,
|
|
7
|
+
:multiple, :temporary, :score, :block, :category
|
|
8
|
+
|
|
9
|
+
# Does this rule's condition block apply?
|
|
10
|
+
def applies?(target_obj = nil)
|
|
11
|
+
return true if block.nil? # no block given: always true
|
|
12
|
+
|
|
13
|
+
case block.arity
|
|
14
|
+
when 1 # Expects target object
|
|
15
|
+
if target_obj.present?
|
|
16
|
+
block.call(target_obj)
|
|
17
|
+
else
|
|
18
|
+
Rails.logger.warn '[merit] no target_obj found on Rule#applies?'
|
|
19
|
+
false
|
|
20
|
+
end
|
|
21
|
+
when 0
|
|
22
|
+
block.call
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Get rule's related Badge.
|
|
27
|
+
def badge
|
|
28
|
+
if badge_id
|
|
29
|
+
Merit::Badge.find(badge_id)
|
|
30
|
+
else
|
|
31
|
+
Merit::Badge.find_by_name_and_level(badge_name, level)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Merit
|
|
2
|
+
class RulesMatcher
|
|
3
|
+
def initialize(path, action_name)
|
|
4
|
+
@path = path
|
|
5
|
+
@action_name = action_name
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def select_from(rules)
|
|
9
|
+
rules.select do |glob, _|
|
|
10
|
+
entire_path =~ /^#{Regexp.new(glob)}$/
|
|
11
|
+
end.values.flatten
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def any_matching?
|
|
15
|
+
select_from(AppBadgeRules).any? || select_from(AppPointRules).any?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def entire_path
|
|
21
|
+
@entire_path ||= [@path, @action_name].join('#')
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Merit
|
|
2
|
+
class SashFinder
|
|
3
|
+
def self.find(rule, action)
|
|
4
|
+
targets(rule, action).map(&:_sash)
|
|
5
|
+
rescue NoMethodError
|
|
6
|
+
Rails.logger.warn "[merit] Couldn't find model to grant reputation to. " \
|
|
7
|
+
"Refer to https://github.com/tute/merit/issues/171#issuecomment-44185696."
|
|
8
|
+
[]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.targets(rule, action)
|
|
12
|
+
TargetFinder.find(rule, action).compact
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Merit
|
|
2
|
+
class TargetFinder < Struct.new(:rule, :action)
|
|
3
|
+
def self.find(*args)
|
|
4
|
+
new(*args).find
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def find
|
|
8
|
+
target = case rule.to
|
|
9
|
+
when :itself then
|
|
10
|
+
base_target
|
|
11
|
+
when :action_user then
|
|
12
|
+
action_user
|
|
13
|
+
else
|
|
14
|
+
other_target
|
|
15
|
+
end
|
|
16
|
+
Array.wrap(target)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def base_target
|
|
22
|
+
BaseTargetFinder.find rule, action
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def action_user
|
|
26
|
+
user = Merit.user_model.find_by_id action.user_id
|
|
27
|
+
if user.nil?
|
|
28
|
+
user_model = Merit.user_model
|
|
29
|
+
str = "[merit] no #{user_model} found with id #{action.user_id}"
|
|
30
|
+
Rails.logger.warn str
|
|
31
|
+
end
|
|
32
|
+
user
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def other_target
|
|
36
|
+
base_target.send rule.to
|
|
37
|
+
rescue NoMethodError
|
|
38
|
+
str = "[merit] NoMethodError on `#{base_target.class.name}##{rule.to}`" \
|
|
39
|
+
' (called from Merit::TargetFinder#other_target)'
|
|
40
|
+
Rails.logger.warn str
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/qalam_merit.gemspec
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Gem::Specification.new do |s|
|
|
2
|
+
s.name = "qalam_merit"
|
|
3
|
+
s.summary = "Reputation engine for Rails apps"
|
|
4
|
+
s.description = "Manage badges, points and rankings (reputation) in your Rails app."
|
|
5
|
+
s.homepage = "https://github.com/merit-gem/merit"
|
|
6
|
+
s.files = `git ls-files`.split("\n").reject{|f| f =~ /^\./ }
|
|
7
|
+
s.test_files = `git ls-files -- test/*`.split("\n")
|
|
8
|
+
s.license = 'MIT'
|
|
9
|
+
s.version = '4.0.4'
|
|
10
|
+
s.authors = ["Tute Costa", "Ahmed Abdelhamid"]
|
|
11
|
+
s.email = ['tutecosta@gmail.com', 'a.hamid@nezam.io']
|
|
12
|
+
|
|
13
|
+
s.required_ruby_version = '>= 2.3.0'
|
|
14
|
+
|
|
15
|
+
s.add_runtime_dependency 'zeitwerk'
|
|
16
|
+
|
|
17
|
+
s.add_development_dependency 'rails', '>= 5.1.6'
|
|
18
|
+
s.add_development_dependency 'capybara'
|
|
19
|
+
s.add_development_dependency 'simplecov'
|
|
20
|
+
s.add_development_dependency 'rubocop'
|
|
21
|
+
s.add_development_dependency 'minitest-rails'
|
|
22
|
+
s.add_development_dependency 'mocha'
|
|
23
|
+
end
|
data/test/dummy/Rakefile
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
|
2
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
|
3
|
+
|
|
4
|
+
require File.expand_path('../config/application', __FILE__)
|
|
5
|
+
require 'rake'
|
|
6
|
+
|
|
7
|
+
Dummy::Application.load_tasks
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
class CommentsController < ApplicationController
|
|
2
|
+
def index
|
|
3
|
+
@comments = Comment.all
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def show
|
|
7
|
+
@comment = Comment.find(params[:id])
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def new
|
|
11
|
+
@comment = Comment.new
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def edit
|
|
15
|
+
@comment = Comment.find(params[:id])
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def vote
|
|
19
|
+
@comment = Comment.find(params[:id])
|
|
20
|
+
@comment.votes += params[:value].to_i
|
|
21
|
+
@comment.save
|
|
22
|
+
redirect_to(comments_url, :notice => 'Vote added!')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def create
|
|
26
|
+
@comment = Comment.new(comment_params)
|
|
27
|
+
if @comment.save
|
|
28
|
+
redirect_to(@comment, :notice => 'Comment was successfully created.')
|
|
29
|
+
else
|
|
30
|
+
render "new"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def update
|
|
35
|
+
@comment = Comment.find(params[:id])
|
|
36
|
+
if @comment.update(comment_params)
|
|
37
|
+
redirect_to(@comment, :notice => 'Comment was successfully updated.')
|
|
38
|
+
else
|
|
39
|
+
render "edit"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# DELETE /comments/1
|
|
44
|
+
# DELETE /comments/1.xml
|
|
45
|
+
def destroy
|
|
46
|
+
@comment = Comment.find(params[:id])
|
|
47
|
+
@comment.destroy
|
|
48
|
+
redirect_to(comments_url)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def comment_params
|
|
54
|
+
params.require(:comment).permit!
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class RegistrationsController < ApplicationController
|
|
2
|
+
def update
|
|
3
|
+
@user = User.find(params[:id])
|
|
4
|
+
|
|
5
|
+
respond_to do |format|
|
|
6
|
+
if @user.update(user_params)
|
|
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
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def user_params
|
|
19
|
+
params.require(:user).permit!
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
class UsersController < ApplicationController
|
|
2
|
+
def index
|
|
3
|
+
@users = User.all
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def show
|
|
7
|
+
@user = User.find(params[:id])
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def new
|
|
11
|
+
@user = User.new
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def edit
|
|
15
|
+
@user = User.find(params[:id])
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def create
|
|
19
|
+
@user = User.new(user_params)
|
|
20
|
+
if @user.save
|
|
21
|
+
redirect_to(@user, :notice => 'User was successfully created.')
|
|
22
|
+
else
|
|
23
|
+
render "new"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def destroy
|
|
28
|
+
@user = User.find(params[:id])
|
|
29
|
+
@user.destroy
|
|
30
|
+
redirect_to(users_url)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def user_params
|
|
36
|
+
params.require(:user).permit!
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
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
|
+
true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# For regression test: if condition doesn't hold, it doesn't check
|
|
30
|
+
# sashes to badge. Useful for polymorphic relations where not every
|
|
31
|
+
# model has reputation. See https://github.com/tute/merit/issues/134.
|
|
32
|
+
grant_on 'users#create', badge: 'just-registered', to: :model_with_no_reputation do |user|
|
|
33
|
+
user.model_with_no_reputation.respond_to?(:_sash)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Example rule for multiple badge granting
|
|
37
|
+
grant_on 'users#index', badge: 'gossip', multiple: true
|
|
38
|
+
|
|
39
|
+
# Example rule for badge granting in namespaced controllers
|
|
40
|
+
grant_on 'admin/users#index', badge: 'visited_admin'
|
|
41
|
+
|
|
42
|
+
# Example rule for testing badge granting in differently namespaced controllers.
|
|
43
|
+
grant_on '.*users#index', badge: 'wildcard_badge', multiple: true
|
|
44
|
+
|
|
45
|
+
# If it has 10 comments, grant commenter-10 badge, find badge by badge_id
|
|
46
|
+
grant_on 'comments#create', badge_id: 1, level: 10 do |comment|
|
|
47
|
+
comment.user.comments.count >= 10
|
|
48
|
+
end
|
|
49
|
+
# Testing badge granting in more than one rule per action with different targets
|
|
50
|
+
grant_on 'comments#create', badge: 'has_commenter_friend', to: :friend do |comment|
|
|
51
|
+
comment.user.comments.count >= 10
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# If it has at least 10 votes, grant relevant-commenter badge
|
|
55
|
+
grant_on 'comments#vote', badge: 'relevant-commenter', to: :user do |comment|
|
|
56
|
+
comment.votes >= 10
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Changes his name by one wider than 4 chars (arbitrary ruby code and custom model_name)
|
|
60
|
+
# This badge is temporary (user may lose it)
|
|
61
|
+
grant_on 'registrations#update', badge: 'autobiographer', temporary: true, model_name: 'User' do |user|
|
|
62
|
+
user.name.length > 4
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|