dawarich/app/services/families/leave.rb
2025-09-28 13:10:07 +02:00

99 lines
2.5 KiB
Ruby

# frozen_string_literal: true
module Families
class Leave
attr_reader :user, :error_message
def initialize(user:)
@user = user
@error_message = nil
end
def call
return false unless validate_can_leave
ActiveRecord::Base.transaction do
handle_ownership_transfer if user.family_owner?
remove_membership
send_notification
end
true
rescue ActiveRecord::RecordInvalid => e
handle_record_invalid_error(e)
false
rescue StandardError => e
handle_generic_error(e)
false
end
private
def validate_can_leave
return false unless validate_in_family
return false unless validate_owner_can_leave
true
end
def validate_in_family
return true if user.in_family?
@error_message = 'You are not currently in a family.'
false
end
def validate_owner_can_leave
return true unless user.family_owner? && family_has_other_members?
@error_message = 'You cannot leave the family while you are the owner and there are ' \
'other members. Remove all members first or transfer ownership.'
false
end
def family_has_other_members?
user.family.members.count > 1
end
def handle_ownership_transfer
# If this is the last member (owner), delete the family
return unless user.family.members.count == 1
user.family.destroy!
# If owner tries to leave with other members, it should be prevented in validation
end
def remove_membership
user.family_membership.destroy!
end
def send_notification
return unless defined?(Notification)
Notification.create!(
user: user,
kind: :info,
title: 'Left Family',
content: "You've left the family"
)
rescue StandardError => e
# Don't fail the entire operation if notification fails
Rails.logger.warn "Failed to send family leave notification: #{e.message}"
end
def handle_record_invalid_error(error)
@error_message = if error.record&.errors&.any?
error.record.errors.full_messages.first
else
"Failed to leave family: #{error.message}"
end
end
def handle_generic_error(error)
Rails.logger.error "Unexpected error in Families::Leave: #{error.message}"
Rails.logger.error error.backtrace.join("\n")
@error_message = 'An unexpected error occurred while leaving the family. Please try again'
end
end
end