Last active
February 26, 2017 22:15
-
-
Save jhubert/1c91cd21264524dde7e07b13832233a2 to your computer and use it in GitHub Desktop.
The after code for my article on Real World Refactoring
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Disable users who have had no activity in the last 14 days | |
class DisableInactiveUsersJob | |
include Sidekiq::Worker | |
def perform | |
users_with_no_activity_since(14.days.ago).pluck(:id).each do |user_id| | |
DisableUser.call(user_id) | |
end | |
end | |
private | |
def users_with_no_activity_since(time) | |
# fairly complicated query for figuring out if users have had activity | |
# omitting for simplicity | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'test_helper' | |
class DisableInactiveUsersJobTest < ActiveSupport::TestCase | |
test "should disable all enabled users who have not had any activity" do | |
DisableInactiveUsers.new.perform | |
User.all.each do |user| | |
assert_predicate user, :disabled? | |
assert Activity.where(target: user, activity: 'user:disable').exists? | |
end | |
end | |
test "should not disable users who are already disabled" do | |
melissa = users(:melissa) | |
melissa.disable! | |
DisableInactiveUsers.new.perform | |
assert_predicate melissa, :disabled? | |
refute Activity.where(target: melissa, activity: 'user:disable').exists? | |
end | |
test "should not disable a user that has had activity within 14 days" do | |
melissa = users(:melissa) | |
Activity.create(activity: 'session:create', user: melissa, created_at: 13.days.ago) | |
DisableInactiveUsers.new.perform | |
melissa.reload | |
assert_predicate melissa, :enabled? | |
refute Activity.where(target: melissa, activity: 'user:disable').exists? | |
end | |
test "should disable a user that has had activity more than 14 days ago" do | |
melissa = users(:melissa) | |
Activity.create(activity: 'session:create', user: melissa, created_at: 15.days.ago) | |
DisableInactiveUsers.new.perform | |
melissa.reload | |
assert_predicate melissa, :disabled? | |
assert Activity.where(target: melissa, activity: 'user:disable').exists? | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Disable users who have email addresses that are bouncing | |
class DisableRejectedEmailsJob | |
include Sidekiq::Worker | |
def perform | |
User.enabled.where(email: rejected_emails).pluck(:id).each do |user_id| | |
DisableUser.call(user_id) | |
end | |
end | |
private | |
# Returns an array of email addresses | |
def rejected_emails | |
# Logic for pulling recently bounced email address from our mail server | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Give an active record model the ability to be enabled / disabled | |
# based on the timestamp value of a column | |
module Disableable | |
extend ActiveSupport::Concern | |
included do | |
scope :enabled, ->(time = Time.zone.now) { where("disabled_at IS NULL OR disabled_at > ?", time) } | |
scope :disabled, ->(time = Time.zone.now) { where("disabled_at < ?", time) } | |
end | |
def disable(time = Time.zone.now) | |
set_disabled_at_value(time) | |
end | |
def disable!(time = Time.zone.now) | |
update_disabled_at_value(time) | |
end | |
def enable | |
set_disabled_at_value(nil) | |
end | |
def enable! | |
update_disabled_at_value(nil) | |
end | |
def enabled?(time = Time.zone.now) | |
!disabled?(time) | |
end | |
def disabled?(time = Time.zone.now) | |
disabled_at && disabled_at <= time | |
end | |
private | |
def set_disabled_at_value(value) # rubocop:disable Style/AccessorMethodName | |
self.disabled_at = value | |
end | |
def update_disabled_at_value(value) | |
update_attribute(:disabled_at, value) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Disable or enable a User by their id | |
class Users::DisablementsController < ApplicationController | |
before_action :load_user, only: [:create, :destroy] | |
def create | |
DisableUser.call(@user.id) | |
redirect_to user_path(@user), notice: I18n.t('user.disablements.create_notice') | |
end | |
def destroy | |
EnableUser.call(@user.id) | |
redirect_to user_path(@user), notice: I18n.t('user.disablements.destroy_notice') | |
end | |
private | |
def load_user | |
@user = User.find(params[:user_id]) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'test_helper' | |
class Users::DisablementsControllerTest < ActionController::TestCase | |
include AuthenticatedAsAdmin | |
test "should enable the intended user" do | |
user = users(:melissa) | |
user.disable! | |
delete :destroy, user_id: user.id | |
user.reload | |
assert_predicate user, :enabled? | |
assert Activity.where(target: user, activity: 'user:enable').exists? | |
end | |
test "should disable the intended user" do | |
user = users(:melissa) | |
post :create, user_id: user.id | |
user.reload | |
assert_predicate user, :disabled? | |
assert Activity.where(target: user, activity: 'user:disable').exists? | |
end | |
# ... more tests for redirection, error messages, etc... | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class User < ActiveRecord::Base | |
include Disableable | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment