Created
April 27, 2022 03:08
-
-
Save joemasilotti/de2275e3be10b51cf959e68d37694343 to your computer and use it in GitHub Desktop.
Service layer extraction
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
# AFTER the refactor | |
class ColdMessage | |
class BusinessBlank < StandardError; end | |
class MissingSubscription < StandardError; end | |
class ExistingConversation < StandardError | |
attr_reader :conversation | |
def initialize(conversation) | |
super | |
@conversation = conversation | |
end | |
end | |
Result = Struct.new(:success?, :message) | |
private attr_reader :options, :user | |
def initialize(options, developer_id:, user:) | |
@options = options | |
@developer_id = developer_id | |
@user = user | |
end | |
def build | |
message = conversation.messages.new(options.merge(sender: business)) | |
if business.blank? | |
raise BusinessBlank.new | |
elsif conversation.persisted? | |
raise ExistingConversation.new(conversation) | |
elsif !active_subscription? | |
raise MissingSubscription.new | |
elsif !MessagingPolicy.new(user, message).create? | |
raise Pundit::NotAuthorizedError.new | |
end | |
message | |
end | |
def send | |
message = build | |
if business.blank? | |
raise BusinessBlank.new | |
elsif conversation.persisted? | |
raise ExistingConversation.new(conversation) | |
elsif !active_subscription? | |
raise MissingSubscription.new | |
elsif !MessagingPolicy.new(user, message).create? | |
raise Pundit::NotAuthorizedError.new | |
elsif !SubscriptionPolicy.new(user, message).messageable? | |
raise Pundit::NotAuthorizedError.new | |
elsif message.save | |
send_recipient_notification(message) | |
Result.new(true, message) | |
else | |
Result.new(false, message) | |
end | |
end | |
private | |
def developer | |
@developer ||= Developer.visible.find(@developer_id) | |
end | |
def business | |
user.business | |
end | |
def conversation | |
@conversation ||= Conversation.find_or_initialize_by(developer:, business:) | |
end | |
def active_subscription? | |
user.active_business_subscription? | |
end | |
def send_recipient_notification(message) | |
NewMessageNotification.with(message:, conversation:).deliver_later(message.recipient.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
# AFTER the refactor | |
class ColdMessagesController < ApplicationController | |
before_action :authenticate_user! | |
rescue_from ColdMessage::BusinessBlank, with: :redirect_to_new_business | |
rescue_from ColdMessage::MissingSubscription, with: :redirect_to_pricing | |
rescue_from ColdMessage::ExistingConversation, with: :redirect_to_conversation | |
def new | |
message = ColdMessage.new({}, developer_id:, user: current_user).build | |
@context = context(message) | |
end | |
def create | |
result = ColdMessage.new(message_params, developer_id:, user: current_user).send | |
if result.success? | |
redirect_to result.message.conversation | |
else | |
@context = context(result.message) | |
render :new, status: :unprocessable_entity | |
end | |
end | |
private | |
def developer_id | |
params[:developer_id] | |
end | |
def context(message) | |
ColdMessageContext.new( | |
message:, | |
messageable: SubscriptionPolicy.new(current_user, message).messageable?, | |
show_hiring_fee_terms: current_user.active_full_time_business_subscription?, | |
tips: MarkdownRenderer.new("cold_messages/tips").render | |
) | |
end | |
def redirect_to_new_business | |
store_location! | |
redirect_to new_business_path, notice: I18n.t("errors.business_blank") | |
end | |
def redirect_to_conversation(e) | |
redirect_to e.conversation | |
end | |
def redirect_to_pricing | |
store_location! | |
redirect_to pricing_path, notice: I18n.t("errors.business_subscription_inactive") | |
end | |
def message_params | |
params.require(:message).permit(:body, :hiring_fee_agreement) | |
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
# BEFORE the refactor | |
class ColdMessagesController < ApplicationController | |
before_action :authenticate_user! | |
before_action :require_business! | |
before_action :require_new_conversation! | |
before_action :require_active_subscription! | |
def new | |
message = Message.new(conversation:) | |
@cold_message = cold_message(message) | |
end | |
def create | |
message = Message.new(message_params.merge(conversation:, sender: business)) | |
if message.save | |
redirect_to message.conversation | |
else | |
@cold_message = cold_message(message) | |
render :new, status: :unprocessable_entity | |
end | |
end | |
private | |
def cold_message(message) | |
ColdMessage.new( | |
message:, | |
messageable: SubscriptionPolicy.new(current_user, message).messageable?, | |
show_hiring_fee_terms: current_user.active_full_time_business_subscription?, | |
tips: MarkdownRenderer.new("cold_messages/tips").render | |
) | |
end | |
def require_business! | |
unless business.present? | |
store_location! | |
redirect_to new_business_path, notice: I18n.t("errors.business_blank") | |
end | |
end | |
def require_new_conversation! | |
redirect_to conversation unless conversation.new_record? | |
end | |
def require_active_subscription! | |
unless current_user.active_business_subscription? | |
store_location! | |
redirect_to pricing_path | |
end | |
end | |
def conversation | |
@conversation ||= Conversation.find_or_initialize_by(developer:, business:) | |
end | |
def developer | |
@developer ||= Developer.find(params[:developer_id]) | |
end | |
def business | |
@business = current_user.business | |
end | |
def message_params | |
params.require(:message).permit(:body, :hiring_fee_agreement) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment