Skip to content

Commit

Permalink
Refactor voucher_processor into model concern
Browse files Browse the repository at this point in the history
According to concepts discussed in #694.
Also auto-load subdirectories in models folder
and set Current.user for usage in models.
  • Loading branch information
Splines committed Oct 8, 2024
1 parent e2786e3 commit d33072d
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 91 deletions.
6 changes: 6 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class ApplicationController < ActionController::Base
before_action :authenticate_user!
before_action :set_locale
after_action :store_interaction, if: :user_signed_in?
before_action :set_current_user

etag { current_user.try(:id) }

Expand Down Expand Up @@ -135,4 +136,9 @@ def cookie_locale_param
def available_locales
I18n.available_locales.map(&:to_s)
end

# https://stackoverflow.com/a/69313330/
def set_current_user
Current.user = current_user
end
end
10 changes: 3 additions & 7 deletions app/controllers/vouchers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def invalidate
end

def verify
@voucher = Voucher.find_voucher_by_hash(check_voucher_params[:secure_hash])
@voucher = Voucher.find_voucher_by_hash(params[:secure_hash])
respond_to do |format|
if @voucher
format.js
Expand All @@ -42,9 +42,9 @@ def verify
end

def redeem
voucher = Voucher.find_voucher_by_hash(check_voucher_params[:secure_hash])
voucher = Voucher.find_voucher_by_hash(params[:secure_hash])
if voucher
VoucherProcessor.call(voucher, current_user, check_voucher_params)
voucher.redeem(params.permit(:tutorial_ids, :talk_ids))
redirect_to edit_profile_path, notice: success_message(voucher)
else
handle_invalid_voucher
Expand All @@ -64,10 +64,6 @@ def voucher_params
params.permit(:lecture_id, :role)
end

def check_voucher_params
params.permit(:secure_hash, tutorial_ids: [], talk_ids: [])
end

def find_voucher
@voucher = Voucher.find_by(id: params[:id])
return if @voucher
Expand Down
Empty file removed app/models/concerns/.keep
Empty file.
4 changes: 4 additions & 0 deletions app/models/current.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html
class Current < ActiveSupport::CurrentAttributes
attribute :user
end
68 changes: 68 additions & 0 deletions app/models/voucher/redeemable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
module Redeemable
extend ActiveSupport::Concern
include Notifier

included do
has_many :redemptions, dependent: :destroy
end

def redeem(params)
case role.to_sym
when :tutor
process_tutor_voucher(params[:tutorial_ids])
when :editor
process_editor_voucher
when :teacher
process_teacher_voucher
when :speaker
process_speaker_voucher(params[:talk_ids])
end
end

private

def process_tutor_voucher(tutorial_ids)
selected_tutorials = lecture.tutorials.where(id: tutorial_ids)
lecture.update_tutor_status!(Current.user, selected_tutorials)

Redemption.create(user: Current.user, voucher: self,
claimed_tutorials: selected_tutorials)
end

def process_editor_voucher
lecture.update_editor_status!(Current.user)
notify_new_editor_by_mail(Current.user, lecture)

Redemption.create(user: Current.user, voucher: self)
end

def process_teacher_voucher
previous_teacher = lecture.teacher
lecture.update_teacher_status!(Current.user)
# no need to send out notifications if the teacher stays the same
# because then there is no demotion to editor
# (it is actually not possible to trigger this case via the GUI)
if previous_teacher != Current.user
notify_about_teacher_change_by_mail(lecture,
previous_teacher)
end
invalidate!

Redemption.create(user: Current.user, voucher: self)
end

def process_speaker_voucher(talk_ids)
selected_talks = lecture.talks.where(id: talk_ids)
lecture.update_speaker_status!(Current.user, selected_talks)
notify_cospeakers_by_mail(Current.user, selected_talks)

Redemption.create(user: Current.user, voucher: self,
claimed_talks: selected_talks)
end

def create_notifications!(redemption)
lecture.editors_and_teacher.each do |editor|
Notification.create(notifiable: redemption, recipient: editor)
end
end
end
File renamed without changes.
2 changes: 2 additions & 0 deletions app/models/voucher.rb → app/models/voucher/voucher.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class Voucher < ApplicationRecord
include Redeemable

SPEAKER_EXPIRATION_DAYS = 30
TUTOR_EXPIRATION_DAYS = 14
DEFAULT_EXPIRATION_DAYS = 3
Expand Down
10 changes: 0 additions & 10 deletions app/services/application_service.rb

This file was deleted.

74 changes: 0 additions & 74 deletions app/services/voucher_processor.rb

This file was deleted.

4 changes: 4 additions & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ class Application < Rails::Application
config.load_defaults(7.1)
config.autoloader = :zeitwerk

# Autoload subfolders of modules (recursively)
# https://stackoverflow.com/a/4794775/
config.autoload_paths += Rails.root.glob("app/models/**/")

# Autoload lib extensions path
config.autoload_lib(ignore: ["assets", "collectors", "core_ext", "scrapers", "tasks"])

Expand Down

0 comments on commit d33072d

Please sign in to comment.