我是一名经验丰富的网络开发人员,但对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
我已经成功创建了一个嵌套表单,允许日记条目及其发布列表一起编辑。但是,大多数日记帐分录都很简单,并且有一个贷记分录和一个借记分录。为了在这种情况下使数据输入更容易,我希望有另一个表单,允许用户只指定信用帐户,借记帐户和金额。
从我的研究中,可以看到两种方法:
SimpleJournalEntry模型将具有信用帐户,借方帐户和金额,并将用于编辑简单记录。现有的JournalEntry模型仍然存在,以允许编辑更复杂的记录。
处理这类事情的'轨道方式'是什么?还有其他选择我没有考虑过吗?
答案 0 :(得分:2)
我不会使用STI来处理这个问题。基本上你有一个简单的“视图”和一个“复杂”视图,底层模型不会改变,只是你要呈现的视图。
创建这个简单视图的备用链接(路径/路径)并管理控制器中保存操作中的“简单性”没有任何问题,您只需检查收到的参数并确定要执行的操作取。
更好的是,将收到的参数传递给日记帐分录模型,并让它处理简单或复杂保存的详细信息。毕竟,与会计相关的业务规则应该在模型中,如果不是的话?
答案 1 :(得分: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