s_a
s_a

Reputation: 65

How to optimize this code

I have used this code in helper to display the count based on the status -

    def to_do_count
        Task.where(status: 0).count
    end 

    def in_progress_count
        Task.where(status: 1).count
    end

    def paused_count
        Task.where(status: 2).count
    end

    def completed_count
        Task.where(status: 3).count
    end

I need help to optimize this code as there are lot of repetitions.

Upvotes: 1

Views: 52

Answers (4)

Pavel Tkackenko
Pavel Tkackenko

Reputation: 953

Option 1

def task_count(status)
  Task
    .where(status: { to_do: 0, in_progress: 1, paused_count: 2, completed_count: 3 }[status])
    .count
end

task_count(:to_do) 
task_count(:in_progress)

Option 2

You can simplify it by using scopes

class Task
  scope :to_do,           -> { where(status: 0) }
  scope :in_progress,     -> { where(status: 1) }
  scope :paused_count,    -> { where(status: 2) }
  scope :completed_count, -> { where(status: 3) }
end

Then helper can look like this:

def task_count(status)
  Task.send(status).count
end

task_count(:to_do)

Upvotes: 1

Hieu Pham
Hieu Pham

Reputation: 6707

You can define a STATUSES constants then define those methods using runtime method definition in Ruby. The code will be like

STATUSES = {
  to_do:       0,
  in_progress: 1,
  paused:      2,
  completed:   3
}

def count_for(status)
  Task.where(status: status).count
end

STATUSES.each do |k, v|
  define_method("#{k}_count"){ count_for(v) }
end

Now you can call all these methods. Since they were defined dynamically

  • to_do_count
  • in_progress_count
  • paused_count
  • completed_count

Upvotes: 1

Deepak Mahakale
Deepak Mahakale

Reputation: 23661

Use hash constant

TASK = {
  to_do: 0,
  in_progress: 1,
  paused_count: 2,
  completed_count: 3
}

def self.count_of(type)
  Task.where(status: TASK[type]).count
end

Call it on class

Task.count_of(:to_do)

Upvotes: 1

Raj
Raj

Reputation: 22926

def count_of(type)
    Task.where(status: get_status_type(type)).count
end 

def get_status_type(type)
   {to_do: 0, in_progress: 1, paused_count: 2, completed_count: 3}[type]
end

Now call:

count_of(:to_do) 

instead of

to_do_count

Upvotes: 1

Related Questions