【问题标题】:Chained aggregate call across association in DataMapper (ruby)DataMapper(ruby)中跨关联的链式聚合调用
【发布时间】:2009-10-24 18:04:52
【问题描述】:

我正在使用 Ruby 中的 Sinatra 和 DataMapper 开发一个简单的预算应用程序。

我想获取过去 30 天内所有收入账户中所有交易的总和。

Account.income_accounts.account_entries.sum(:amount, :transaction_date.gte => Date.today - 30) 之类的东西应该可以工作。相反,transaction_date 上的限制条件被忽略,返回所有收入账户的所有条目的金额总和。

鉴于以下情况:

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

我正确地要求dm-aggregates。我是 DataMapper 的新手。如果重要的话,我使用的是 sqlite3 数据库。我真的不想诉诸使用 ruby​​ 来总结结果。对这种类型的简单聚合查询执行原始 SQL 也是错误的。

任何人都可以对此有所了解吗?我很想指出关于 DataMapper 中的链式查找器的正确方向,尤其是聚合。我对 API 和 DataMapper 站点的深入研究尚未产生解决方案。

【问题讨论】:

    标签: ruby datamapper


    【解决方案1】:

    我刚刚编写了一个小的独立脚本来测试您的示例,它似乎返回了正确的结果。请注意,我使用的是从 git 安装的 edge extlib、dm-core 和 dm-more:

    #!/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
    

    你能运行上面的程序并告诉我它为你返回了什么吗?如果您得到的不是 5.0,请尝试更新到最新的软件包并重试。

    【讨论】:

    • 您在 :transaction_date 中有日期,而他有 DateTime。会这样吗?
    【解决方案2】:

    DateTime 使用秒作为它的基本单位 Date.today - 30 是 30 之前。试试Date.today - 30.days

    【讨论】:

    • Date.today - 30 给了我 2009-09-24 的预期。
    【解决方案3】:

    您是否尝试过 DateTime.now-30 甚至 Time.now-30*3600*24 而不是 Date.today-30 ?

    【讨论】:

      【解决方案4】:

      用户错误。我在DateTime 上使用to_s 来使用strftime 中的时间格式。移除后,链式聚合按预期工作。

      【讨论】:

        猜你喜欢
        • 2010-12-22
        • 1970-01-01
        • 2013-05-07
        • 1970-01-01
        • 1970-01-01
        • 2012-07-01
        • 2016-06-27
        • 2017-08-11
        • 2012-03-27
        相关资源
        最近更新 更多