0

我是一位经验丰富的 Web 开发人员,但对 Rails 很陌生。我正在编写基于复式记帐数据库的预算应用程序。数据库包含表示交易的日记帐分录,每个日记帐分录有多个过帐。每个过帐都有一个帐户和一个金额。

以下是我的模型的简化版本:

class Posting < ActiveRecord::Base
  belongs_to :account
  belongs_to :journal_entry

  attr_accessible :account_id, :amount
end

class JournalEntry < ActiveRecord::Base
  has_many :postings, :dependent => :destroy

  attr_accessible :narrative, :posting_date, :postings_attributes

  accepts_nested_attributes_for :postings, :allow_destroy => :true,
    :reject_if => proc { |attrs| attrs.all? { |k, v| k == '_destroy' or v.blank? } } 
end

我已经成功创建了一个嵌套表单,它允许一起编辑日记帐条目及其帖子列表。但是,大多数日记帐分录都很简单,只有一个贷记分录和一个借记分录。在这种情况下,为了使数据输入更容易,我想要另一个表单,允许用户指定贷方账户、借方账户和金额。

根据我的研究,可以看到两种方法:

  1. 单表继承,其中 SimpleJournalEntry(扩展 JournalEntry)
  2. 使用 ActiveModel 制作不直接附加到数据库的 SimpleJournalEntry 模型,并在控制器中自己处理数据库更改

SimpleJournalEntry 模型将具有贷方账户、借方账户和金额,并将用于编辑简单记录。现有的 JournalEntry 模型仍然存在,以允许编辑更复杂的记录。

处理这种事情的“轨道方式”是什么?还有其他我没有考虑过的选择吗?

4

2 回答 2

2

在这一点上,我不得不不同意 railsdog 的观点。我认为你确实有一个很好的 STI 候选人。特别是,我认为“让 [JournalEntry] 处理简单或复杂保存的细节”表明您正在处理两个独立的问题。

如果您的简单和复杂的 JournalEntries 具有不同的业务逻辑,它们应该由两个不同的类来表示。不难想象,例如,复杂的 JournalEntry 可能想要添加简单的 JournalEntry 没有的验证。或者简单的 JournalEntry 应该比复杂的 JournalEntry 有更少的 attr_accessible 声明。我会建议:

class JournalEntry < ActiveRecord::Base
  # shared accessors and validations
end

class SimpleJournalEntry < JournalEntry
  # simple accessors and validations 
end

class ComplexJournalEntry < JournalEntry
  # more complex accessors and validations
end

我将使用单独的控制器和视图来处理这两个类。

在不相关的注释中,#accepts_nested_attributes_for 的 :all_blank 选项应该做你的 Proc 所做的事情,不是吗?来自文档:“传递 :all_blank 而不是 Proc 将创建一个 proc,它将拒绝所有属性为空的记录,不包括 _destroy 的任何值。” 那是,accepts_nested_attributes_for :postings, :reject_if => :all_blank

于 2012-06-18T05:36:25.490 回答
2

I would not use STI to handle this. Essentially you have a simple 'view' and a 'complex' view, the underlying model(s) aren't changing, just the view you want to present.

There is nothing wrong with creating alternate link (path/route) to this simple view, and managing the 'simplicity' in the save action in your controller, you'll just have to inspect the params received and decide which action to take.

Even better, pass the params as received to your journal entry model, and let it handle the details of the simple or complicated save. After all, the business rules associated with accounting should be in the model, should they not?

于 2012-06-18T04:32:18.973 回答