Суммируйте общее поле в ActiveRecord, используя инъекцию в Ruby / Rails

mayorsanmayor спросил: 31 июля 2018 в 09:46 в: ruby-on-rails

Помогите мне понять эту ошибку ActiveRecord, а также, пожалуйста, сообщите мне правильный способ написать это.

У меня есть модель оплаты

class Payment < ApplicationRecord  enum status: %w(success, failed, initialized)  scope :successful, -> { where(status: :success) }  def self.find_total_amount_spent(user_id)
    total_amount = 0
    total_amount = self.where(user_id: user_id, status: :success).inject(0) {|amount, payment| amount + payment.amount }
    return total_amount/100.0
  end
end

В find_total_amount_spent, я хочу получить общую сумму, потраченную пользователем.

Но я получаю эту ошибку

ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: "success" SELECT "payments".* FROM "payments" WHERE "payments"."user_id" = $1 AND "payments"."status" = $2):

Мое понимание этой ошибки состоит в том, что я не должен передавать символ :success, но я использовал его в других частях моего приложения, где он работал. Более того, он также используется в enum doc

Является ли это, что инъекция ожидает, что каждое значение, переданное ему, является целым числом? Да, это то, о чем я думал, основываясь на моем понимании инъекции отсюда

Итак, если инъекция не является правильным методом для использования здесь, не могли бы вы объяснить я лучший подход и лучший способ найти решение?

Большое спасибо.

1 ответ

Есть решение
Ursus ответил: 31 июля 2018 в 10:02

Ваша проблема не имеет ничего общего с методом inject. Речь идет о вашем определении перечисления.

Этот

%w(success, failed, initialized)

оценивается как

["success,", "failed,", "initialized"]

Избавиться от этих запятых :)

enum status: %w(success failed initialized)

В любом случае, использование SQL было бы намного лучше

def self.find_total_amount_spent(user_id)
  (successful.where(user_id: user_id).sum(:amount) || 0) / 100.0
end
Arup Rakshit ответил: 31 июля 2018 в 09:56
Это одна ошибка. Еще одна вещь, которую нужно исправить, если вы не в Rails 5, это то, что вам нужно передать фактическое целое число. Как self.where(user_id: user_id, status: self.statuses['success'] .. Потому что это то, что ошибки SQL-запроса. Фактический столбец является целым числом, но вы передаете ему строку.
mayorsanmayor ответил: 31 июля 2018 в 10:00
Большое вам спасибо, я чувствую себя так глупо. Учитывая, что я знаю об этом еще до сих пор. Все в порядке, я в Rails 5, и теперь он работает, ошибка исчезла. Другой вопрос, который у меня есть, это лучший способ суммировать эти значения? что происходит, когда у пользователя есть 100 записей об этом платеже? Может быть лучше написать с помощью Reduce (: +)?
Ursus ответил: 31 июля 2018 в 10:00
Да, есть лучший способ: использовать SQL. Позвольте мне обновить мой ответ.
Arup Rakshit ответил: 31 июля 2018 в 10:02
@mayorsanmayor self.where(user_id: user_id, status: :success).sum(:amout) / 100
Ursus ответил: 31 июля 2018 в 10:04
Дайте мне знать, если это работает