Pergunta

Eu estou trabalhando em um aplicativo simples orçamento usando Sinatra e DataMapper em Ruby.

Eu quero obter a soma de todas as operações em todas as contas de resultado nos últimos 30 dias.

Algo como Account.income_accounts.account_entries.sum(:amount, :transaction_date.gte => Date.today - 30) deve funcionar. Em vez disso, a condição limitante na transaction_date está sendo ignorado, retornando a soma do montante para todas as entradas para todas as contas de resultado.

Dado o seguinte:

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

Eu estou exigindo adequadamente dm-aggregates. Eu sou novo para DataMapper. Se é importante, eu estou usando um banco de dados sqlite3. Eu realmente não quero recorrer ao uso de rubi para somar os resultados. Ele também se sente mal que recorrer a execução de SQL cru para este tipo de consulta de agregação simples.

Alguém pode lançar alguma luz sobre isso? Eu adoraria ser apontado na direção certa sobre localizadores acorrentados em DataMapper, particularmente com agregados. Meu espeleologia na API e no site DataMapper não produziu uma solução até o momento.

Foi útil?

Solução 4

erro do usuário. I fez muck ao redor com to_s em DateTime usar os formatos de hora em strftime. Quando removida, o agregado encadeado funcionou como previsto.

Outras dicas

Eu escrevi um pequeno script stand-alone para testar o seu exemplo, e parece para retornar os resultados corretos. Por favor, note que estou usando extlib borda, dm-core, e dm-mais, tudo instalado a partir de 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

Você pode executar o programa acima e deixe-me saber o que ele retorna para você? Se você receber algo diferente de 5.0, tente atualizar com os últimos pacotes e tente novamente.

DateTime usa segunda como da unidade de base Date.today - 30 é de 30 segundos atrás. Tente Date.today - 30.days

Você tentou DateTime.now-30 ou talvez até Time.now-30 * 3600 * 24, em vez de Date.today-30?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top