Llamada agregada encadenada a través de la asociación en DataMapper (ruby)
-
06-07-2019 - |
Pregunta
Estoy trabajando en una aplicación de presupuesto simple utilizando Sinatra y DataMapper en Ruby.
Quiero obtener la suma de todas las transacciones en todas las cuentas de ingresos en los últimos 30 días.
Algo como Account.income_accounts.account_entries.sum (: amount,: transaction_date.gte = > Date.today - 30)
debería funcionar. En cambio, la condición límite en transaction_date
se ignora, devolviendo la suma de la cantidad de todas las entradas para todas las cuentas de ingresos.
Teniendo en cuenta lo siguiente:
class Account
include DataMapper::Resource
has n, :account_entries
property :id, Serial
property :name, String
property :acct_type, String
def self.income_accounts
all(:acct_type => 'Income')
end
end
class AccountEntry
include DataMapper::Resource
belongs_to :account
property :id, Serial
property :account_id, Integer
property :description, String
property :amount, BigDecimal
property :transaction_date, DateTime
end
Exijo correctamente dm-aggregates
. Soy nuevo en DataMapper. Si importa, estoy usando una base de datos sqlite3. Realmente no quiero recurrir al uso de ruby ??para sumar los resultados. También se siente mal recurrir a la ejecución de SQL sin formato para este tipo de consulta agregada simple.
¿Alguien puede arrojar algo de luz sobre esto? Me encantaría ser apuntado en la dirección correcta con respecto a los buscadores encadenados en DataMapper, particularmente con agregados. Mi búsqueda en la API y el sitio DataMapper no ha dado aún una solución.
Solución 4
Error de usuario. Me cagué con to_s
en DateTime
para usar los formatos de hora en strftime
. Cuando se eliminó, el agregado encadenado funcionó como se anticipó.
Otros consejos
Acabo de escribir una pequeña secuencia de comandos independiente para probar su ejemplo, y parece que devuelve los resultados correctos. Tenga en cuenta que estoy usando Edge Extlib, dm-core y dm-more todo instalado desde git:
#!/usr/bin/env ruby -Ku
# encoding: utf-8
require 'rubygems'
require 'dm-core'
require 'dm-aggregates'
DataMapper::Logger.new($stdout, :debug)
DataMapper.setup(:default, 'sqlite3::memory:')
class Account
include DataMapper::Resource
property :id, Serial
property :name, String
property :acct_type, String
has n, :account_entries
def self.income_accounts
all(:acct_type => 'Income')
end
end
class AccountEntry
include DataMapper::Resource
property :id, Serial
property :description, String
property :amount, BigDecimal
property :transaction_date, Date
belongs_to :account
end
DataMapper.auto_migrate!
account = Account.create(
:name => 'Test Account',
:acct_type => 'Income'
)
5.times do |n|
account.account_entries.create(
:description => "Account Entry #{n}",
:amount => 1.00,
:transaction_date => Date.today
)
end
puts Account.income_accounts.account_entries(:transaction_date.gte => Date.today - 30).sum(:amount).to_s('F') # => 5.0
¿Puedes ejecutar el programa anterior y decirme qué devuelve para ti? Si obtiene algo distinto a 5.0, intente actualizar a los paquetes más recientes y vuelva a intentarlo.
DateTime usa el segundo como su unidad base Date.today - 30
hace 30 segundos . Pruebe Date.today - 30.days
¿Intentaste DateTime.now-30 o incluso Time.now-30 * 3600 * 24 en lugar de Date.today-30?