我到处都读到业务逻辑属于模型而不是控制器,但限制在哪里?我在玩个人会计应用程序。
Account
Entry
Operation
创建操作时,仅当创建相应条目并将其链接到帐户以使操作平衡时才有效,例如购买 6 件装:
o=Operation.new({:description=>"b33r", :user=>current_user, :date=>"2008/09/15"})
o.entries.build({:account_id=>1, :amount=>15})
o.valid? #=>false
o.entries.build({:account_id=>2, :amount=>-15})
o.valid? #=>true
现在在基本操作的情况下向用户显示的表单被简化以隐藏条目详细信息,帐户是根据用户请求的操作类型在 5 个默认值中选择的(初始化帐户 -> 净值帐户,花费资产 - >费用,赚取收入->资产,借入负债->资产,支付债务资产->负债......)我想要从默认值创建的条目。
我还希望能够创建更复杂的操作(超过 2 个条目)。对于第二个用例,我将有一个不同的形式,其中暴露了额外的复杂性。第二个用例阻止我在操作中包含借方和贷方字段并摆脱输入链接。
哪种形式最好?像我现在一样在 SimpleOperationController 中使用上面的代码,或者在 Operation 类上定义一个新方法,这样我就可以调用 Operation.new_simple_operation(params[:operation])
从 Operation 类中实际创建和操作 Entry 对象不是破坏了关注点分离吗?
我不是在寻求关于我扭曲的会计原则的建议 :)
编辑——看来我表达得不太清楚。我不太关心验证。我更关心创建逻辑代码应该去哪里:
假设控制器上的操作称为支出,当使用支出时,参数哈希将包含:金额、日期、描述。借方和贷方账户将派生自被调用的操作,但随后我必须创建所有对象。拥有会不会更好
#error and transaction handling is left out for the sake of clarity
def spend
amount=params[:operation].delete(:amount)#remove non existent Operation attribute
op=Operation.new(params[:operation])
#select accounts in some way
...
#build entries
op.entries.build(...)
op.entries.build(...)
op.save
end
或在 Operation 上创建一个方法,使上面看起来像
def spend
op=Operation.new_simple_operation(params)
op.save
end
这肯定会提供更薄的控制器和更胖的模型,但随后模型将创建和存储其他模型的实例,这就是我的问题所在。