qalam_merit 4.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/CODE_OF_CONDUCT.md +84 -0
  4. data/Gemfile +10 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +358 -0
  7. data/RELEASING.md +16 -0
  8. data/Rakefile +44 -0
  9. data/TESTING.txt +12 -0
  10. data/config/locales/en.yml +5 -0
  11. data/lib/merit.rb +95 -0
  12. data/lib/merit/badge_rules_methods.rb +30 -0
  13. data/lib/merit/base_target_finder.rb +31 -0
  14. data/lib/merit/class_methods.rb +41 -0
  15. data/lib/merit/controller_extensions.rb +71 -0
  16. data/lib/merit/generators/active_record/install_generator.rb +40 -0
  17. data/lib/merit/generators/active_record/merit_generator.rb +25 -0
  18. data/lib/merit/generators/active_record/remove_generator.rb +30 -0
  19. data/lib/merit/generators/active_record/templates/add_merit_fields_to_model.erb +7 -0
  20. data/lib/merit/generators/active_record/templates/create_badges_sashes.erb +14 -0
  21. data/lib/merit/generators/active_record/templates/create_merit_actions.erb +16 -0
  22. data/lib/merit/generators/active_record/templates/create_merit_activity_logs.erb +12 -0
  23. data/lib/merit/generators/active_record/templates/create_merit_badges.erb +17 -0
  24. data/lib/merit/generators/active_record/templates/create_sashes.erb +8 -0
  25. data/lib/merit/generators/active_record/templates/create_scores_and_points.erb +16 -0
  26. data/lib/merit/generators/active_record/templates/remove_merit_fields_from_model.erb +7 -0
  27. data/lib/merit/generators/active_record/templates/remove_merit_tables.erb +12 -0
  28. data/lib/merit/generators/install_generator.rb +30 -0
  29. data/lib/merit/generators/merit_generator.rb +33 -0
  30. data/lib/merit/generators/remove_generator.rb +23 -0
  31. data/lib/merit/generators/templates/badge.erb +69 -0
  32. data/lib/merit/generators/templates/merit.erb +18 -0
  33. data/lib/merit/generators/templates/merit_badge_rules.erb +50 -0
  34. data/lib/merit/generators/templates/merit_point_rules.erb +31 -0
  35. data/lib/merit/generators/templates/merit_rank_rules.erb +32 -0
  36. data/lib/merit/generators/templates/qalam_badge_sash.erb +20 -0
  37. data/lib/merit/generators/templates/qalam_sash.erb +14 -0
  38. data/lib/merit/judge.rb +102 -0
  39. data/lib/merit/models/action_concern.rb +50 -0
  40. data/lib/merit/models/active_record/action.rb +11 -0
  41. data/lib/merit/models/active_record/activity_log.rb +11 -0
  42. data/lib/merit/models/active_record/badges_sash.rb +13 -0
  43. data/lib/merit/models/active_record/sash.rb +32 -0
  44. data/lib/merit/models/active_record/score.rb +25 -0
  45. data/lib/merit/models/badges_sash_concern.rb +13 -0
  46. data/lib/merit/models/base/badges_sash.rb +15 -0
  47. data/lib/merit/models/base/sash.rb +55 -0
  48. data/lib/merit/models/sash_concern.rb +53 -0
  49. data/lib/merit/point_rules_methods.rb +33 -0
  50. data/lib/merit/rank_rules_methods.rb +58 -0
  51. data/lib/merit/reputation_change_observer.rb +19 -0
  52. data/lib/merit/rule.rb +35 -0
  53. data/lib/merit/rules_matcher.rb +24 -0
  54. data/lib/merit/sash_finder.rb +15 -0
  55. data/lib/merit/target_finder.rb +43 -0
  56. data/qalam_merit.gemspec +23 -0
  57. data/test/dummy/Rakefile +7 -0
  58. data/test/dummy/app/controllers/admin/users_controller.rb +9 -0
  59. data/test/dummy/app/controllers/api/comments_controller.rb +5 -0
  60. data/test/dummy/app/controllers/api/users_controller.rb +5 -0
  61. data/test/dummy/app/controllers/application_controller.rb +7 -0
  62. data/test/dummy/app/controllers/comments_controller.rb +56 -0
  63. data/test/dummy/app/controllers/registrations_controller.rb +21 -0
  64. data/test/dummy/app/controllers/users_controller.rb +38 -0
  65. data/test/dummy/app/helpers/application_helper.rb +2 -0
  66. data/test/dummy/app/models/address.rb +3 -0
  67. data/test/dummy/app/models/comment.rb +13 -0
  68. data/test/dummy/app/models/dummy_observer.rb +3 -0
  69. data/test/dummy/app/models/merit/badge_rules.rb +66 -0
  70. data/test/dummy/app/models/merit/point_rules.rb +44 -0
  71. data/test/dummy/app/models/merit/rank_rules.rb +24 -0
  72. data/test/dummy/app/models/user.rb +23 -0
  73. data/test/dummy/app/views/admin/users/index.html.erb +26 -0
  74. data/test/dummy/app/views/comments/_form.html.erb +29 -0
  75. data/test/dummy/app/views/comments/edit.html.erb +6 -0
  76. data/test/dummy/app/views/comments/index.html.erb +35 -0
  77. data/test/dummy/app/views/comments/new.html.erb +5 -0
  78. data/test/dummy/app/views/comments/show.html.erb +23 -0
  79. data/test/dummy/app/views/layouts/application.html.erb +24 -0
  80. data/test/dummy/app/views/users/_form.html.erb +22 -0
  81. data/test/dummy/app/views/users/edit.html.erb +6 -0
  82. data/test/dummy/app/views/users/index.html.erb +27 -0
  83. data/test/dummy/app/views/users/new.html.erb +5 -0
  84. data/test/dummy/app/views/users/show.html.erb +18 -0
  85. data/test/dummy/config.ru +4 -0
  86. data/test/dummy/config/application.rb +26 -0
  87. data/test/dummy/config/application_api_only.rb +28 -0
  88. data/test/dummy/config/boot.rb +10 -0
  89. data/test/dummy/config/database.yml +22 -0
  90. data/test/dummy/config/environment.rb +5 -0
  91. data/test/dummy/config/environment_api_only.rb +7 -0
  92. data/test/dummy/config/environments/development.rb +24 -0
  93. data/test/dummy/config/environments/production.rb +51 -0
  94. data/test/dummy/config/environments/test.rb +36 -0
  95. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  96. data/test/dummy/config/initializers/inflections.rb +10 -0
  97. data/test/dummy/config/initializers/merit.rb +47 -0
  98. data/test/dummy/config/initializers/mime_types.rb +5 -0
  99. data/test/dummy/config/initializers/new_framework_defaults.rb +3 -0
  100. data/test/dummy/config/initializers/secret_token.rb +12 -0
  101. data/test/dummy/config/initializers/session_store.rb +8 -0
  102. data/test/dummy/config/locales/en.yml +5 -0
  103. data/test/dummy/config/mongoid.yml +13 -0
  104. data/test/dummy/config/routes.rb +16 -0
  105. data/test/dummy/db/migrate/20110421191249_create_users.rb +12 -0
  106. data/test/dummy/db/migrate/20110421191250_create_comments.rb +16 -0
  107. data/test/dummy/db/migrate/20120318022220_add_fields_to_users.rb +11 -0
  108. data/test/dummy/db/migrate/20130321082817_add_fields_to_comments.rb +11 -0
  109. data/test/dummy/db/migrate/20130329224406_create_merit_actions.rb +18 -0
  110. data/test/dummy/db/migrate/20130329224407_create_merit_activity_logs.rb +15 -0
  111. data/test/dummy/db/migrate/20130329224408_create_sashes.rb +11 -0
  112. data/test/dummy/db/migrate/20130329224409_create_badges_sashes.rb +16 -0
  113. data/test/dummy/db/migrate/20130329224410_create_scores_and_points.rb +20 -0
  114. data/test/dummy/db/migrate/20140211144001_create_addresses.rb +11 -0
  115. data/test/dummy/db/migrate/20140819133931_add_target_data_to_merit_actions.rb +5 -0
  116. data/test/dummy/db/schema.rb +89 -0
  117. data/test/dummy/db/seeds.rb +19 -0
  118. data/test/dummy/public/404.html +26 -0
  119. data/test/dummy/public/422.html +26 -0
  120. data/test/dummy/public/500.html +26 -0
  121. data/test/dummy/public/favicon.ico +0 -0
  122. data/test/dummy/public/rails.js +404 -0
  123. data/test/dummy/public/stylesheets/.gitkeep +0 -0
  124. data/test/dummy/public/stylesheets/scaffold.css +56 -0
  125. data/test/dummy/script/rails +6 -0
  126. data/test/integration/navigation_test.rb +332 -0
  127. data/test/support/integration_case.rb +5 -0
  128. data/test/test_helper.rb +40 -0
  129. data/test/unit/action_test.rb +12 -0
  130. data/test/unit/base_target_finder_test.rb +64 -0
  131. data/test/unit/merit_unit_test.rb +33 -0
  132. data/test/unit/rule_unit_test.rb +57 -0
  133. data/test/unit/rules_matcher_test.rb +37 -0
  134. data/test/unit/sash_finder_test.rb +27 -0
  135. data/test/unit/sash_test.rb +104 -0
  136. data/test/unit/score_test.rb +13 -0
  137. data/test/unit/target_finder_test.rb +98 -0
  138. metadata +360 -0
data/RELEASING.md ADDED
@@ -0,0 +1,16 @@
1
+ # Releasing
2
+
3
+ 1. Update `NEWS.md` to reflect the changes since last release.
4
+ 1. Tag the release: `git tag vVERSION -a -s`. The tag message should contain the
5
+ appropriate `NEWS.md` subsection.
6
+ 1. Push changes: `git push --tags`
7
+ 1. Build and publish to rubygems:
8
+ ```bash
9
+ gem build merit.gemspec
10
+ gem push merit-*.gem
11
+ ```
12
+
13
+ 1. Add a new GitHub release:
14
+ https://github.com/merit-gem/merit/releases/new?tag=vVERSION
15
+ 1. Announce the new release, making sure to say "thank you" to the contributors
16
+ who helped shape this version!
data/Rakefile ADDED
@@ -0,0 +1,44 @@
1
+ # encoding: UTF-8
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ require 'rake/testtask'
9
+
10
+ desc 'Default: run tests for all ORMs.'
11
+ task default: [:setup, :test, :api_test]
12
+
13
+ task :setup do
14
+ system "cd test/dummy && rake db:migrate && rake db:test:prepare"
15
+ end
16
+
17
+ Rake::TestTask.new(:test) do |t|
18
+ t.libs << 'lib'
19
+ t.libs << 'test'
20
+ t.pattern = 'test/**/*_test.rb'
21
+ t.verbose = true
22
+ end
23
+
24
+ Rake::TestTask.new(:api_test) do |t|
25
+ t.libs << 'lib'
26
+ t.libs << 'test'
27
+ t.test_files = FileList['test/**/*_test.rb'].exclude(/navigation_test.rb/)
28
+ t.verbose = true
29
+ t.options = '-- -api-only'
30
+ end
31
+
32
+ begin
33
+ require 'rdoc/task'
34
+ Rake::RDocTask.new(:rdoc) do |rdoc|
35
+ rdoc.rdoc_dir = 'rdoc'
36
+ rdoc.title = 'Merit'
37
+ rdoc.options << '--line-numbers' << '--inline-source'
38
+ rdoc.rdoc_files.include('README.md')
39
+ rdoc.rdoc_files.include('lib/**/*.rb')
40
+ end
41
+ rescue LoadError
42
+ puts 'This platform does not support RDocTask'
43
+ end
44
+
data/TESTING.txt ADDED
@@ -0,0 +1,12 @@
1
+ # run tests
2
+ rake
3
+
4
+ # Or spin up self contained testing Rails application
5
+ cd test/dummy
6
+ rails g merit:install
7
+ rails g merit user
8
+ rails g merit comment
9
+ rake db:migrate db:seed
10
+
11
+ # see it in the browser
12
+ rails server
@@ -0,0 +1,5 @@
1
+ en:
2
+ merit:
3
+ granted_badge: "granted %{badge_name} badge"
4
+ granted_points: "granted %{points} points"
5
+ removed_badge: "removed %{badge_name} badge"
data/lib/merit.rb ADDED
@@ -0,0 +1,95 @@
1
+ require 'zeitwerk'
2
+
3
+ module Merit
4
+ def self.setup
5
+ @config ||= Configuration.new
6
+ yield @config if block_given?
7
+ end
8
+
9
+ # Check rules on each request
10
+ def self.checks_on_each_request
11
+ @config.checks_on_each_request
12
+ end
13
+
14
+ def self.orm
15
+ @config.orm || :active_record
16
+ end
17
+
18
+ # Define user_model_name
19
+ def self.user_model
20
+ @config.user_model_name.constantize
21
+ end
22
+
23
+ # Define current_user_method
24
+ def self.current_user_method
25
+ @config.current_user_method ||
26
+ "current_#{@config.user_model_name.downcase}".to_sym
27
+ end
28
+
29
+ def self.observers
30
+ @config.observers
31
+ end
32
+
33
+ # @param class_name [String] The string version of observer class
34
+ def self.add_observer(class_name)
35
+ @config.add_observer(class_name)
36
+ end
37
+
38
+ class Configuration
39
+ attr_accessor :checks_on_each_request, :orm, :user_model_name, :observers,
40
+ :current_user_method
41
+
42
+ def initialize
43
+ @checks_on_each_request = true
44
+ @orm = :active_record
45
+ @user_model_name = 'User'
46
+ @observers = []
47
+ end
48
+
49
+ def add_observer(class_name)
50
+ @observers << class_name
51
+ end
52
+ end
53
+
54
+ setup
55
+ add_observer('Merit::ReputationChangeObserver')
56
+
57
+ class BadgeNotFound < StandardError; end
58
+ class RankAttributeNotDefined < StandardError; end
59
+
60
+ class Engine < Rails::Engine
61
+ config.app_generators.orm Merit.orm
62
+
63
+ initializer 'merit.controller' do |app|
64
+ extend_orm_with_has_merit
65
+ ActiveSupport.on_load(action_controller_hook) do
66
+ begin
67
+ # Load app rules on boot up
68
+ Merit::AppBadgeRules = Merit::BadgeRules.new.defined_rules
69
+ Merit::AppPointRules = Merit::PointRules.new.defined_rules
70
+ include Merit::ControllerExtensions
71
+ rescue NameError => e
72
+ # Trap NameError if installing/generating files
73
+ raise e unless
74
+ e.to_s =~ /uninitialized constant Merit::(BadgeRules|PointRules)/
75
+ end
76
+ end
77
+ end
78
+
79
+ def extend_orm_with_has_merit
80
+ ActiveRecord::Base.include(Merit)
81
+ end
82
+
83
+ def action_controller_hook
84
+ if Rails.application.config.api_only
85
+ :action_controller_api
86
+ else
87
+ :action_controller_base
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ loader = Zeitwerk::Loader.for_gem
94
+ loader.setup
95
+ loader.eager_load
@@ -0,0 +1,30 @@
1
+ module Merit
2
+ module BadgeRulesMethods
3
+ # Define rule for granting badges
4
+ def grant_on(actions, *args, &block)
5
+ options = args.extract_options!
6
+
7
+ actions = Array.wrap(actions)
8
+
9
+ rule = Rule.new
10
+ rule.badge_id = options[:badge_id]
11
+ rule.badge_name = options[:badge]
12
+ rule.level = options[:level]
13
+ rule.to = options[:to] || :action_user
14
+ rule.multiple = options[:multiple] || false
15
+ rule.temporary = options[:temporary] || false
16
+ rule.model_name = options[:model_name] || actions.first.split('#').first
17
+ rule.block = block
18
+
19
+ actions.each do |action|
20
+ defined_rules[action] ||= []
21
+ defined_rules[action] << rule
22
+ end
23
+ end
24
+
25
+ # Currently defined rules
26
+ def defined_rules
27
+ @defined_rules ||= {}
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ module Merit
2
+ class BaseTargetFinder
3
+ def self.find(*args)
4
+ new(*args).find
5
+ end
6
+
7
+ def initialize(rule, action)
8
+ @rule = rule
9
+ @action = action
10
+ end
11
+
12
+ def find
13
+ get_target_from_database || reanimate_target_from_action
14
+ rescue => e
15
+ Rails.logger.warn "[merit] no target found: #{e}. #{caller.first}"
16
+ end
17
+
18
+ def get_target_from_database
19
+ model_class.find_by_id(@action.target_id)
20
+ end
21
+
22
+ def model_class
23
+ klass_name = (@rule.model_name || @action.target_model).singularize
24
+ klass_name.camelize.constantize
25
+ end
26
+
27
+ def reanimate_target_from_action
28
+ YAML.load(@action.target_data)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,41 @@
1
+ module Merit
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+ def has_merit(options = {})
6
+ # MeritableModel#sash_id is more stable than Sash#meritable_model_id
7
+ # That's why MeritableModel belongs_to Sash. Can't use
8
+ # dependent: destroy as it may raise FK constraint exceptions. See:
9
+ # https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/1079-belongs_to-dependent-destroy-should-destroy-self-before-assocation
10
+ belongs_to :sash, class_name: 'Merit::Sash', inverse_of: nil, optional: true
11
+
12
+ _merit_delegate_methods_to_sash
13
+ _merit_define_badge_related_entries_method
14
+ _merit_sash_initializer
15
+ end
16
+
17
+ # Delegate methods from meritable models to their sash
18
+ def _merit_delegate_methods_to_sash
19
+ methods = %w(badge_ids badges points add_badge rm_badge
20
+ add_points subtract_points score_points)
21
+ methods.each { |method| delegate method, to: :_sash }
22
+ end
23
+
24
+ def _merit_define_badge_related_entries_method
25
+ meritable_class_name = name.demodulize
26
+ Merit::Badge._define_related_entries_method(meritable_class_name)
27
+ end
28
+
29
+ # _sash initializes a sash if doesn't have one yet.
30
+ # From Rails 3.2 we can override association methods to do so
31
+ # transparently, but merit supports Rails ~> 3.0.0. See:
32
+ # http://blog.hasmanythrough.com/2012/1/20/modularized-association-methods-in-rails-3-2
33
+ def _merit_sash_initializer
34
+ define_method(:_sash) do
35
+ # TODO: reload.sash is not regression tested
36
+ sash || reload.sash || update(sash: Sash.create)
37
+ sash
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,71 @@
1
+ module Merit
2
+ # Sets up an app-wide after_filter, and inserts merit_action entries if
3
+ # there are defined rules (for badges or points) for current
4
+ # 'controller_path#action_name'
5
+ module ControllerExtensions
6
+ def self.included(base)
7
+ base.after_action :log_and_process
8
+ end
9
+
10
+ private
11
+
12
+ def log_and_process
13
+ if rules_defined?
14
+ Merit::Action.create(merit_action_hash)
15
+
16
+ if Merit.checks_on_each_request
17
+ Merit::Action.check_unprocessed
18
+ end
19
+ end
20
+ end
21
+
22
+ def merit_action_hash
23
+ {
24
+ user_id: send(Merit.current_user_method).try(:id),
25
+ action_method: action_name,
26
+ action_value: params[:value],
27
+ had_errors: had_errors?,
28
+ target_model: controller_path,
29
+ target_id: target_id,
30
+ target_data: target_object.to_yaml,
31
+ }
32
+ end
33
+
34
+ def rules_defined?
35
+ RulesMatcher.new(controller_path, action_name).any_matching?
36
+ end
37
+
38
+ def had_errors?
39
+ target_object.respond_to?(:errors) && target_object.errors.try(:present?)
40
+ end
41
+
42
+ def target_object
43
+ variable_name = :"@#{controller_name.singularize}"
44
+ if instance_variable_defined?(variable_name)
45
+ if target_obj = instance_variable_get(variable_name)
46
+ target_obj
47
+ else
48
+ warn_no_object_found
49
+ end
50
+ end
51
+ end
52
+
53
+ def warn_no_object_found
54
+ str = '[merit] No object found, you might need a ' \
55
+ "'@#{controller_name.singularize}' variable in " \
56
+ "'#{controller_path}_controller' if no reputation is applied. " \
57
+ 'If you are using `model_name` option in the rule this is ok.'
58
+ Rails.logger.warn str
59
+ nil
60
+ end
61
+
62
+ def target_id
63
+ target_id = target_object.try(:id)
64
+ # If target_id is nil use (only digits of) params[:id]
65
+ if target_id.nil? && params[:id].to_s =~ /^[0-9]+$/
66
+ target_id = params[:id]
67
+ end
68
+ target_id
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,40 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ module Merit
4
+ module Generators::ActiveRecord
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+
8
+ source_root File.expand_path('../templates', __FILE__)
9
+ desc 'add active_record merit migrations for the root objects'
10
+
11
+ def self.next_migration_number(path)
12
+ ActiveRecord::Generators::Base.next_migration_number(path)
13
+ end
14
+
15
+ def copy_migrations_and_model
16
+ migration_template 'create_merit_actions.erb',
17
+ 'db/migrate/create_merit_actions.rb'
18
+ sleep 1.1
19
+ migration_template 'create_merit_activity_logs.erb',
20
+ 'db/migrate/create_merit_activity_logs.rb'
21
+ sleep 1.1
22
+ migration_template 'create_merit_badges.erb',
23
+ 'db/migrate/create_merit_badges.rb'
24
+ sleep 1.1
25
+ migration_template 'create_sashes.erb',
26
+ 'db/migrate/create_sashes.rb'
27
+ sleep 1.1
28
+ migration_template 'create_badges_sashes.erb',
29
+ 'db/migrate/create_badges_sashes.rb'
30
+ sleep 1.1
31
+ migration_template 'create_scores_and_points.erb',
32
+ 'db/migrate/create_scores_and_points.rb'
33
+ end
34
+
35
+ def migration_version
36
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,25 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ module Merit
4
+ module Generators::ActiveRecord
5
+ class MeritGenerator < ::ActiveRecord::Generators::Base
6
+ include Rails::Generators::Migration
7
+
8
+ source_root File.expand_path('../templates', __FILE__)
9
+ desc 'add active_record merit migrations'
10
+
11
+ def self.next_migration_number(path)
12
+ ActiveRecord::Generators::Base.next_migration_number(path)
13
+ end
14
+
15
+ def copy_migrations_and_model
16
+ migration_template 'add_merit_fields_to_model.erb',
17
+ "db/migrate/add_merit_fields_to_#{table_name}.rb"
18
+ end
19
+
20
+ def migration_version
21
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,30 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ module Merit
4
+ module Generators::ActiveRecord
5
+ class RemoveGenerator < ::ActiveRecord::Generators::Base
6
+ include Rails::Generators::Migration
7
+
8
+ source_root File.expand_path('../templates', __FILE__)
9
+ desc 'Creates a migration file to remove all traces of Merit on the DB'
10
+
11
+ def self.next_migration_number(path)
12
+ ActiveRecord::Generators::Base.next_migration_number(path)
13
+ end
14
+
15
+ def copy_migrations_and_model
16
+ migration_template 'remove_merit_tables.erb',
17
+ 'db/migrate/remove_merit_tables.rb'
18
+
19
+ migration_template(
20
+ 'remove_merit_fields_from_model.erb',
21
+ "db/migrate/remove_merit_fields_from_#{table_name}.rb"
22
+ )
23
+ end
24
+
25
+ def migration_version
26
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
27
+ end
28
+ end
29
+ end
30
+ end