Skip to content

Instantly share code, notes, and snippets.

@jhubert
Last active February 26, 2017 22:16
Show Gist options
  • Save jhubert/2975dc03f1201203cd9961328a811bdd to your computer and use it in GitHub Desktop.
Save jhubert/2975dc03f1201203cd9961328a811bdd to your computer and use it in GitHub Desktop.
The before code for my article on refactoring in the real world
# Disable users who have had no activity in the last 14 days
class DisableInactiveUsersJob
include Sidekiq::Worker
def perform
now = Time.zone.now
target_users = users_with_no_activity_since(now - 14.days)
# Load the ids before we update the users or the pluck query will return nothing
target_user_ids = target_users.pluck(:id)
target_users.update_all(disabled_at: now)
target_user_ids.each { |user_id| track_disabling_of(user_id) }
end
private
def track_disabling_of(user_id)
Activity.track(
'user:disable',
target_type: User.name,
target_id: user_id
)
end
def users_with_no_activity_since(time)
# fairly complicated query for figuring out if users have had activity
# omitting for simplicity
end
end
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::DB.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::DB.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::DB.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::DB.where(target: melissa, activity: 'user:disable').exists?
end
end
# 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
# Disable or enable a User by their id
class Users::DisablementsController < ApplicationController
before_action :load_user, only: [:create, :destroy]
def create
@user.disable!
track_activity('user:disable', target: @user)
redirect_to user_path(@user), notice: I18n.t('user.disablements.create_notice')
end
def destroy
@user.enable!
track_activity('user:enable', target: @user)
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
require 'test_helper'
class Users::DisablementsControllerTest < ActionController::TestCase
include AuthenticatedAsAdmin
test "should enable the intended user" do
user = users(:melissa)
user.disable!
@controller.expects(:track_activity).with('user:enable', target: user)
delete :destroy, user_id: user.id
user.reload
assert_predicate user, :enabled?
end
test "should disable the intended user" do
user = users(:melissa)
@controller.expects(:track_activity).with('user:disable', target: user)
post :create, user_id: user.id
user.reload
assert_predicate user, :disabled?
end
# ... more tests for redirection, error messages, etc...
end
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