假设您正在为一家滑雪板租赁店实现 Rails 应用。
给定的滑雪板可以处于 3 种状态之一:
- 离开进行维护
- X 店有售
- 借给客户 Y
公司需要能够查看租赁历史
- 一个特定的滑雪板
- 特定客户
租赁历史需要包括时间数据(例如,Sally 从 2009 年 12 月 1 日到 2009 年 12 月 3 日租用了滑雪板 0123)。
您将如何设计您的模型?您是否有一个包含 4 列(id、状态、客户、商店)的滑雪板表,并在每次状态更改时将此表中的行连同时间戳复制到 snowboard_history 表?
谢谢!
(注意:我实际上并不是在尝试实现租赁商店;这只是我能想到的最简单的类比。)
最佳答案
我会使用一对插件来完成工作。这将使用四个模型。滑雪板、商店、用户和审计。
acts_as_state_machine和 acts_as_audited
AASM 简化了状态转换。审核会创建您想要的历史记录。
Store 和 User 的代码很简单,acts_as_audited 将处理审计模型。
class Snowboard < ActiveRecord::Base
include AASM
belongs_to :store
aasm_initial_state :unread
acts_as_audited :only => :state
aasm_state :maintenance
aasm_state :available
aasm_state :rented
aasm_event :send_for_repairs do
transitions :to => :maintenance, :from => [:available]
end
aasm_event :return_from_repairs do
transitions :to => :available, :from => [:maintenance]
end
aasm_event :rent_to_customer do
transitions :to => :rented, :from => [:available]
end
aasm_event :returned_by_customer do
transitions :to => :available, :from => [:rented]
end
end
class User < ActiveRecord::Base
has_many :full_history, :class_name => 'Audit', :as => :user,
:conditions => {:auditable_type => "Snowboard"}
end
假设您的客户是状态更改时 Controller 操作期间的 current_user,这就是您所需要的。
获取滑雪板历史记录:
@snowboard.audits
获取客户的租赁历史:
@customer.full_history
您可能想要创建一个辅助方法来将客户的历史记录变成更有用的东西。也许像他的东西:
def rental_history
history = []
outstanding_rentals = {}
full_history.each do |item|
id = item.auditable_id
if rented_at = outstanding_rentals.keys.delete(id)
history << {
:snowboard_id => id,
:rental_start => rented_at,
:rental_end => item.created_at
}
else
outstanding_rentals[:id] = item.created_at
end
end
history << oustanding_rentals.collect{|key, value| {:snowboard_id => key,
:rental_start => value}
end
end
关于ruby-on-rails - 在 Rails 中实现租赁商店 : how to track an inventory state over time?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1741034/