Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for fat model refactor

I'm trying to make my fat User model less clunky. I'm using value objects to represent custom values and operations on them, and am stuck with ActiveSupport::Concerns and modules. I read this as an inspiration.

I put helper methods like this:

def is_a_wizard?
  power_level >= WIZARD_POWER
end

def just_became_a_wizard?
  power_level == WIZARD_POWER
end

into modules, and included them as sort of extensions. However, it is hard to read and maintain, and I need some of them both in views and controllers (for example for wizard authentication). Where should I put them? Create service objects for when they're used?

like image 324
Piotr Kruczek Avatar asked Nov 01 '22 03:11

Piotr Kruczek


1 Answers

You can create additional class and use it wherever you want:

# lib/wizard_detector.rb
class WizardDetector
  def initialize(power_level)
    @power_level = power_level
  end

  def is_a_wizard?
    @power_level >= WIZARD_POWER
  end

  def just_became_a_wizard?
    @power_level == WIZARD_POWER
  end 
end

# app/models/user.rb
class User

  delegate :is_a_wizard?, :just_became_a_wizard?, to: :wizard_detector

  def wizard_detector
    @wizard_detector ||= WizardDetector.new(power_level)
  end
end

# anywhere else
WizardDetector.new(power_level_to_check).is_a_wizard?

Please notice wizard_detector object is cached in model, maybe it is harmful if power level changes during request flow. It's ok to replace caching.

like image 183
hedgesky Avatar answered Nov 09 '22 05:11

hedgesky