Last active
January 3, 2016 14:29
-
-
Save nicholasjhenry/8476503 to your computer and use it in GitHub Desktop.
Refactoring of a Policy example from DAS
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
# session_controller.rb | |
class SessionsController | |
def create | |
user = log_user_in | |
AccountStandingPolicy.new(@user).enforce! | |
end | |
end | |
# account_standing_policy.rb | |
class AccountStandingPolicy | |
def initialize(user) | |
@user = user | |
end | |
def valid? | |
@user.all_cards_invalid? | |
end | |
def enforce! | |
if valid? | |
@user.disable! | |
send_disable_notification! | |
end | |
end | |
def send_disable_notification! | |
# ... | |
end | |
end | |
# user.rb | |
class User | |
has_many :cards | |
def disable! | |
update_attribute(:enabled, false) | |
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
# session_controller.rb | |
class SessionsController | |
def create | |
authorize_user = AuthorizeUser.new | |
authorize_user.add_listener( | |
EnforceAccountStandingPolicy.new( | |
AccountStandingPolicy.new | |
DisableUser.new | |
) | |
) | |
end | |
end | |
# enforce_account_standing_policy.rb | |
class EnforceAccountStandingPolicy | |
def initialize(policy, service) | |
@policy, @service = policy, service | |
end | |
def login_successful(user) | |
enforce!(user) | |
end | |
private | |
def enforce!(user) | |
return if @policy.comply?(user) | |
@service.call(user) | |
end | |
end | |
# account_standing_policy.rb | |
class AccountStandingPolicy | |
def comply?(user) | |
user.all_cards_invalid? | |
end | |
end | |
# disable_user.rb | |
class DisableUser | |
def call(user) | |
disable_user!(user) | |
send_disable_notification!(user) | |
end | |
def disable_user!(user) | |
user.disable! | |
end | |
def send_disable_notification!(user) | |
#... | |
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
# controllers/session_controller.rb | |
class SessionsController < ApplicationController | |
def create | |
authorize_user = AuthorizeUser.new | |
authorize_user.add_listener( | |
EnforceAccountStandingPolicyService.build | |
) | |
end | |
end | |
# Services encapsulate application logic | |
# | |
# services/enforce_account_standing_policy_service.rb | |
class EnforceAccountStandingPolicyService < Service | |
# Factory method to setup dependencies | |
# | |
def build | |
self.new( | |
DisableUser.new( | |
AccountStandingPolicy.new | |
) | |
) | |
end | |
# TODO: can we inject multiple commands? | |
# | |
def initialize(command) | |
@command = command | |
end | |
def login_successful(user) | |
call(user) | |
end | |
private | |
def call(user) | |
@command.call(user) | |
send_disable_notification | |
end | |
def send_disable_notification!(user) | |
#... | |
end | |
end | |
# Commands encapsulate domain logic | |
# | |
# commands/disable_user.rb | |
class DisableUser | |
def initialize(policy) | |
@policy = policy | |
end | |
def call(user) | |
return if @policy.comply?(user) | |
user.disable! | |
end | |
end | |
# Policies reify business rules | |
# | |
# policies/account_standing_policy.rb | |
class AccountStandingPolicy | |
def comply?(user) | |
user.all_cards_invalid? | |
end | |
end | |
# Active record objects are treated as Row Data Gateway | |
# | |
# data/user.rb | |
class User < ActiveRecord::Base | |
def disable! | |
update(enable: false) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment