我是一位經驗豐富的Web開發人員,但是對於rails而言是新手。我正在編寫基於複式會計數據庫的預算申請。數據庫包含日記帳分錄以表示交易,並且每個日記帳分錄具有多個過帳。每個發佈都有一個帳戶和一個金額。我已將借方金額表示爲負值,將信用額表示爲正值。對1個模型字段使用2個虛擬屬性
但是,我不希望用戶記住正面和負面的情況,所以我已經爲我的模型製作了信用額度和借記金額的虛擬屬性,以便用戶可以看到單獨的信用額度和借項金額字段。
張貼模型是如下:
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
這是使用2個虛擬屬性(credit_amount和debit_amount)爲1個模型字段(量)的正確方法?我嘗試爲credit_amount/debit_amount編寫getter和setter,直接使用基礎數量字段,但這意味着我無法準確地向用戶報告驗證錯誤。
我同意Anil的做法是好的。可能還有其他方法可以做到,但這足夠直觀。儘管有關代碼的一些評論(拿走或離開)。 1)我將你的驗證正則表達式提取爲一個常量,因爲它在兩個地方使用。常數名稱將更好地記錄意圖是什麼。 2)Ruby開發人員傾向於喜歡&&,|| 3)從方法返回以避免額外縮進(在check_amounts中,返回如果@ account_id.blank?)4)使用reader方法而不是實例變量(account_id vs @account_id) –
感謝您的反饋和指導風格的鏈接 - 我錯過了我的搜索。我熱衷於學習ruby的風格習慣以及rails方式。 – Nathan
雄辯Ruby是學習Ruby風格和最佳實踐的好書。 –