【问题标题】:Using 2 virtual attributes for 1 model field对 1 个模型字段使用 2 个虚拟属性
【发布时间】:2012-06-17 07:30:39
【问题描述】:

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

但是,我不希望用户记住正面和负面,因此我在模型上为贷方金额和借方金额制作了虚拟属性,以便用户看到单独的贷方金额和借方金额字段。

Posting 模型如下:

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

  attr_accessible :account_id, :credit_amount, :debit_amount
  attr_accessor :credit_amount, :debit_amount

  after_validation :set_amount
  after_find :split_amount

  validates :credit_amount, :format => { :with => /\A(?:\d+(?:\.\d{1,2})?|(?:.\d{1,2}))?\z/ }
  validates :debit_amount,  :format => { :with => /\A(?:\d+(?:\.\d{1,2})?|(?:.\d{1,2}))?\z/ }

  validate :check_amounts

  def check_amounts
    unless @account_id.blank?
      if not @debit_amount.blank? and not @credit_amount.blank?
        errors.add(:base, "cannot specify both credit and debit amount.")
      elsif @debit_amount.blank? and @credit_amount.blank?
        errors.add(:base, "must specify one of credit or debit amount.")
      end
    end
  end

  protected

  def set_amount
    unless @debit_amount.blank? and @credit_amount.blank?
      self.amount = @debit_amount.blank? ? BigDecimal.new(@credit_amount) : -BigDecimal.new(@debit_amount)
    end
  end

  def split_amount
    @credit_amount = (self.amount.nil? or self.amount >= 0) ? self.amount : nil
    @debit_amount = (self.amount.nil? or self.amount >= 0) ? nil : -self.amount
  end
end

这是为 1 个模型字段(金额)使用 2 个虚拟属性(credit_amount 和 debit_amount)的正确方法吗?我尝试编写直接使用基础金额字段的 credit_amount/debit_amount 的 getter 和 setter,但这意味着我无法准确地向用户报告验证错误。

【问题讨论】:

  • 我同意 Anil 的观点,即这种方法很好。您可能还有其他方法可以做到这一点,但这足够直观。只是关于代码的几个问题(接受或离开)。 1)我会将您的验证正则表达式提取为一个常量,因为它在两个地方使用。常量名称将更好地记录意图是什么。 2) Ruby 开发者更喜欢 &&, || over and, or (github.com/styleguide/ruby) 3) 从方法返回以避免额外缩进(在 check_amounts 中,如果 @account_id.blank 则返回?) 4) 使用读取器方法而不是实例变量(account_id 与 @account_id)
  • 感谢您的反馈和风格指南的链接 - 我在搜索中错过了这些。我很想学习 ruby​​ 的样式约定以及 rails 方式。
  • Eloquent Ruby 是一本学习 Ruby 风格和最佳实践的好书。

标签: ruby-on-rails ruby-on-rails-3


【解决方案1】:

我喜欢你写它的方式。使用正则表达式的贷方金额和借方金额验证比仅将这些字段验证为数字更严格。 split amount 方法可以使用上面的注释来解释你在那里做什么,这样下一个在凌晨 3:00 调试的人就不必弄清楚(实际上,正则表达式也可以使用明确的描述注释)。

我希望这会有所帮助。

祝你好运!

【讨论】:

  • 感谢您的回答 - 将添加您建议的 cmets
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
相关资源
最近更新 更多