Mi Ro
Mi Ro

Reputation: 760

rails sort collection by custom method

I have a method which takes ID of project and find all payments, do the math and the output is percentage of success (target amount vs collected)

def projectCollectedMoneyPerc(id)
    @project= Project.find(id)
    @collected = Payment.where('project_id = ? and confirmed = true', @project.id)
    @col = @collected.sum(:amount)

    @perc = ((@col.to_f / @project.amount) * 100).round(0)
end

now I need to find projects which have most % success. My idea was to call this method by sort_by but I have no idea how to put ID from collection to this sort

my collection is simple

@projects=Project.where('enabled = true and enddate > ?', Time.now)

thanks

Upvotes: 0

Views: 900

Answers (1)

spickermann
spickermann

Reputation: 106832

I would define a method like to following in your model:

# in app/models/project.rb
has_many :payments

def collected_money_percentage
  sum = payments.where(confirmed: true).sum(:amount)
  (100.0 * sum / amount ).round
end

Then you cound use that method like this:

Project.where('enabled = true and enddate > ?', Time.now)
       .sort_by(&:collected_money_percentage)

Please note that this first loads all matching record and then calculations the percentage in memory. It would probably be faster to calculate this values in your database:

Project.joins(:payments)
  .where('enabled = true and enddate > ?', Time.now)
  .group('projects.id')
  .order('SUM(payments.amount) / projects.amount')

Upvotes: 2

Related Questions