Adding by block in ruby

I sent a similar question to this not so long ago regarding formatting a MySQL query using a block and received very good answers, but they were very specific to the problem. This time I ran into getting rows .sum()in a table. Here is what I have now:

def balance
  balance = 0
  items.each do |item|
    balance = balance + item.charges.sum(:revenue, :conditions => ['created_at >= ?', Time.now.beginning_of_month])
  end
  balance
end

My goal is to get the total amount of all fees for this month for this user. Fees refer to items that belong to users. I am sure the best way to do this is in Ruby / Rails.

What would you do?

+3
source share
4 answers

You can perform a direct conversion:

def balance
  conds = ["created_at > ?", Time.now.beginning_of_month]
  items.inject(0) do |total, item|
    total + item.charges.sum(:revenue, :conditions => conds)
  end
end

, , . , - :

def balance
  Charge.sum :revenue,
    :conditions => ["charges.item_id IN (?) AND created_at > ?",
      items.map { |item| item.id },
      Time.now.beginning_of_month]
end

map, inject, select .. . RDoc Enumerable .

+5

SQL-, :

Charges.sum :revenue, :conditions => [ "created_at >= ?, items.user_id = ?",
                                        Time.now.beginning_of_month, some_user_id ],
                      :joins => :items

: , sum : , find. , : join :

:joins => "JOIN items ON charges.item_id = items.id"
+2

:

  • , , , Skinny Controller, Fat Model.
  • balance = balance + item.charges.sum(:revenue, :conditions => ['created_at >= ?', Time.now.beginning_of_month]) += : balance += item.charges.sum(:revenue, :conditions => ['created_at >= ?', Time.now.beginning_of_month]).
  • , , (.. "" ).
  • Time.now.beginning_of_month , .
+1

. , , , Smalltalk inject:into:. Ruby inject reduce ( ).

The idea is that you have a set of values, and you want to "reduce" or "collapse" this collection of several values ​​into a single value. (The Smalltalk name inject:into:comes from entering an initial value in the block that is called for each item in the collection.)

def balance
  this_month = Time.now.beginning_of_month
  items.reduce(0) { |balance, item|
    balance + item.charges.sum(:revenue, :conditions => ['created_at >= ?', this_month])
  }
end
+1
source

Source: https://habr.com/ru/post/1725319/


All Articles