Ruby设计模式:在一个类中保存多种类型的对象

时间:2011-09-11 14:10:42

标签: ruby-on-rails ruby design-patterns

我正在Rails中构建一个复式会计系统,其中包括:

  • 用户。属性:user_id。关系:has_many:accounts
  • 帐户。属性:user_id。关系:belongs_to:user,postss
  • 杂志。属性:id。关系:has_many:发布,belongs_to:period
  • 张贴。属性:journal_id,account_id,points。关系:belongs_to:journal,:account。

对于从帐户1到帐户2的每笔交易,将有两个过帐,一个在帐户1上,一个在帐户2上,还有一个日记对象用于描述整个交易。

帐户的主要方法是:

def transfer (destination, amount, description=nil)
  Journal.transfer self, destination, amount, description
end

将从Journal调用transfer方法生成Postings:

def self.transfer( source, destination, amount, description=nil)
     transaction do
          j = create! :description => description, :period_id => p.id
          Posting.create! :journal_id => j.id, :account_id => source.id,  
                          :points    => -Integer(amount)
          Posting.create! :journal_id => j.id, :account_id => destination.id, 
                          :points =>  Integer(amount)

在此处查看有关此系统的更多详细信息:http://homepages.tcp.co.uk/~m-wigley/gc_wp_ded.html

现在,我想要允许账户1“承诺”某些积分到账户2.通过抵押,账户1将无法再访问这些积分。如果稍后,帐户1授权该交易,则帐户2可以使用这些点。

我只能想到一种方法(从this discussion学习):

为每个用户创建两个帐户,“已结算”和“已抵押”。当1个承诺时,积分将从1个结算账户转移到2个承诺账户。当1批准时,积分将从2的质押账户转移到结算账户。

为了实现这一点,我在Account中添加了一个“account_type”列,枚举了“pledged”和“已结算” 但是,它看起来不正确,因为当用户想要做出承诺时,他必须找出他应该从哪个帐户类型发送点,以及他应该发送给哪种类型的帐户。由于此更改,帐户现在无法像以前一样代表用户进行转移决策,因为每个用户都有多个帐户。

现在,我可以向User类添加传输功能,然后选择他拥有的account_type,然后从该帐户发送点数。但我不想要金融系统和我系统的一般部分之间的紧密联系。

我可以添加一个“包装”类AccountManager,它与User有一对一的关系,可以选择从哪个帐户发送点。但似乎有点不必要的复杂。

我还可以添加用于转移,结算的方法类,这将查找适当的帐户类型以进行转移。但它看起来也不正确。

我认为我不能修改Posting以便它可以顺利处理,但我可能错了。

所以我想就如何解决这个问题提出建议。

谢谢。

1 个答案:

答案 0 :(得分:1)

用户实际上没有两个帐户(或帐户类型),而是有待处理或已完成的转帐。当我在银行工作(特别是信用卡/借记卡支付处理)时,一切都以这种方式处理,因为一些资金每隔 n 小时通过批处理文件传输。

简言之,那是一个中间步骤。初始付款会从 1 的帐户中移除资金。资金申请被标记为待审,直到 2 的银行获得资金申请并进行处理。一旦处理完毕,资金需求就完成了,一切都应该如此。

如果由于某种原因退款或其他原因,资金申请将被取消,资金将返还 1

此过程异步(显然)发生,但与实时请求一起生效。在我们的系统中,以相同的方式表示,但它不需要 - 在您的情况下,您可以像现在一样处理直接转移,并使用两步流程处理承诺。

在我们的系统中,资金申请处理充当期刊 - 我们可以通过查看资金申请更新历史来重新创建/跟踪任何付款的路径。我不确定在你的系统中处理它的最佳方法是什么;我最初的猜测是提交一份日记帐以及一次接受,并且状态表明他们是两阶段转移的一部分。

不确定这有多大帮助,但这是在现实生活中(或多或少)处理这种情况的一种方式。

相关问题