2009-10-24 4 views
1

Je travaille sur une application de budget simple en utilisant Sinatra et DataMapper dans Ruby.Appel agrégé chaîné à travers l'association dans DataMapper (ruby)

Je veux obtenir la somme de toutes les transactions pour tous les comptes de revenu au cours des 30 derniers jours.

Quelque chose comme Account.income_accounts.account_entries.sum(:amount, :transaction_date.gte => Date.today - 30) devrait fonctionner. Au lieu de cela, la condition de limitation sur transaction_date est ignorée, renvoyant la somme du montant pour toutes les entrées pour tous les comptes de revenus.

Compte tenu de ce qui suit:

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 

Je suis bien dm-aggregates NÉCESSITANT. Je suis nouveau à DataMapper. Si c'est important, j'utilise une base de données sqlite3. Je ne veux vraiment pas avoir recours à l'utilisation de rubis pour additionner les résultats. Il est également incorrect de recourir à l'exécution de SQL brut pour ce type de requête agrégée simple.

Quelqu'un peut-il nous éclairer à ce sujet? J'aimerais être pointé dans la bonne direction en ce qui concerne les finders enchaînés dans DataMapper, en particulier avec les agrégats. Ma spéléologie dans l'API et le site DataMapper n'a pas encore donné de solution.

Répondre

0

Erreur de l'utilisateur. Je mucked autour avec to_s sur DateTime pour utiliser les formats d'heure dans strftime. Lorsqu'il a été retiré, l'agrégat enchaîné a fonctionné comme prévu.

0

DateHeure utilise la seconde comme unité de base Date.today - 30 est 30 secondes. Essayez Date.today - 30.days

+0

Date.today - 30 me donne 2009-09-24 comme prévu. – kEND

0

Avez-vous essayé DateTime.now-30 ou peut-être même Time.now-30 * 3600 * 24 au lieu de Date.today-30?

2

Je viens d'écrire un petit script autonome pour tester votre exemple, et il semble retourner les bons résultats. S'il vous plaît noter que je me sers de bord extlib, dm-core et dm-plus INSTALLE 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 

Pouvez-vous exécuter le programme ci-dessus et laissez-moi savoir ce qu'il retourne pour vous? Si vous obtenez autre chose que 5.0, essayez de mettre à jour les derniers paquets et réessayez.

+0

Vous avez Date dans: transaction_date et DateTime. Est-ce que ça pourrait être ça? –