2016-05-01 2 views
1

Я пытаюсь выполнить replicate this с запросом базы данных Rails, но не имеет большой удачи.Сумма всех сумм, если created_at совпадают в Rails

Мой Foo стол имеет много столбцов, но меня интересуют created_at и amount.

Foo.all.where(client_id: 4) выглядит следующим образом:

[ 
    [0] {:created_at => <date>, :amount => 20}, 
    [1] {:created_at => <different date>, :amount => 5}, 
    ... 
] 

Stripe Charge Object в формате JSON, поэтому я думал, что я мог бы:

f = Foo.all.where(client_id: 4).as_json # could I? 

Во всяком случае, мой контроллер:

# As per first link above 
def each_user_foo 
    starting_after = nil 
    loop do 
    f = Foo.all.where(client_id: 4).as_json 
    #f_hash = Hash[f.each_slice(2).to_a] # I was trying something here 
    break if f.none? 
    f.each do |bar| 
     yield bar 
    end 
    starting_after = bar.last.id 
    end 
end 

foo_by_date = Hash.new(0) 

each_user_foo do |f| 
    # Parses date object. `to_date` converts a DateTime object to a date (daily resolution). 
    amount_date = DateTime.strptime(f.created_at.to_s, "%s").to_date # line 50 
    amount = f.amount 

    # Initialize the amount for this date to 0. 
    foo_by_date[amount_date] ||= 0 

    foo_by_date[amount_date] += amount 
end 

Моя ошибка в строка 50:

неопределенный метод `created_at» для Hash

Я предполагаю, что объект все еще находится в массиве где-то. Кроме того, существует ли эквивалент JS console.log() в Rails? Было бы удобно.

ответ

1

Похоже f хранится как объект Hash, вызвав as_json, но вы рассматривая его как обычный-старый объект Ruby, в вашем each_user_foo блоке с помощью оператора ..

Решение заключается в использовании оператора доступа хеширования (например, f[:created_at]). Вам также не нужно stringify и разобрать дату, потому что это уже DateTime объект:

amount_date = f[:created_at].to_date # line 50 
amount = f[:amount] 

Кроме того, Foo модель класса правильно? Если да, то я бы рекомендовал использовать pluck получить атрибуты, необходимые, которые будут более эффективными и чище, чем вызов as_json:

# As per first link above 
def each_user_foo 
    f = Foo.where(client_id: 4).pluck(:created_at, :amount) 
    f.each do |bar| 
     yield(bar.first, bar.last) 
    end 
end 

foo_by_date = Hash.new(0) 

each_user_foo do |created_at, amount| 
    # Parses date object. `to_date` converts a DateTime object to a date (daily resolution). 
    amount_date = created_at.to_date # line 50 
    foo_by_date[amount_date] += amount 
end 

Вы можете удалить эту линию, а также:

foo_by_date[amount_date] ||= 0 

С вы используете инициализатор в своем назначении переменной foo_by_date = Hash.new(0)).

EDIT

Если вы используете Postgres, просто сделать:

Foo.where(client_id: 4).group("date_trunc('day', created_at)").sum(:amount) 

Или для MySQL:

Foo.where(client_id: 4).group("DAY(created_at)").sum(:amount) 

Многое, гораздо проще, чем ваш подход.

Эквивалент console.log() в Rails - Rails.logger.info(), вы также можете использовать Rails.logger.warn() и Rails.logger.error().Действительно, любая функция, которая выводится на STDOUT, например puts и print, выводит на консоль.

+0

Ahh thanks. Im теперь получает 'undefined method' [] 'для Sun, 01 мая 2016 07:07:35 UTC +00: 00: Time', когда я использую' pluck'. – Sylar

+0

На той же строке, что и ваша первая ошибка? –

+0

Позвольте мне проверить все. – Sylar

Смежные вопросы