代码之家  ›  专栏  ›  技术社区  ›  splicer

在Rails中实现租赁商店:如何随时间跟踪库存状态?

  •  3
  • splicer  · 技术社区  · 15 年前

    假设您正在为滑雪板租赁商店实施rails应用程序。

    给定的滑雪板可以处于以下三种状态之一:

    1. 外出维修
    2. 借出给客户Y

    公司需要能够查看的租赁历史记录

    • 一种特殊的滑雪板
    • 特定客户

    租赁历史记录需要包括时间数据(例如,Sally从2009年12月1日至2009年12月3日租用了滑雪板0123)。

    谢谢

    (注意:我实际上并没有试图实现租赁商店;这只是我能想到的最简单的模拟。)

    2 回复  |  直到 15 年前
        1
  •  10
  •   fkoessler    4 年前

    我会使用一对插件来完成这项工作。这将使用四种型号。滑雪板、商店、用户和审计。

    acts_as_state_machine acts_as_audited

    AASM简化了状态转换。而审核会创建所需的历史记录。

    Store和User的代码很简单,它将处理审计模型。

    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    
    

    假设您的客户是控制器操作期间的当前用户,当状态发生变化时,这就是您所需要的。

    @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
    
        2
  •  2
  •   joukokar    15 年前

    script/generate model Snowboard name:string price:integer ...
    script/generate model Customer name:string ...
    script/generate model Store name:string ...
    

    id created_at , modified_at (日期)

    相反,我会创建滑雪板活动模型(你可以称之为 SnowboardHistory

    • ev_type (即0表示归还,1表示维护,2表示租赁…)
    • snowboard_id (非空)
    • customer_id
    • store_id

    例如

    script/generate model SnowboardEvent ev_type:integer snowboard_id:integer \
        customer_id:integer store_id:integer
    

    然后我就把所有的关系 SnowboardEvent , Snowboard Customer Store . 滑雪板可以有如下功能 current_state current_store 实施为

    class Snowboard < ActiveRecord::Base
      has_many :snowboard_events
      validates_presence_of :name
    
      def initialize(store)
        ev = SnowboardEvent.new(
             {:ev_type => RETURN,
              :store_id => store.id,
              :snowboard_id = id,
              :customer_id => nil})
        ev.save
      end
    
      def current_state
        ev = snowboard_events.last
        ev.ev_type          
      end
    
      def current_store
        ev = snowboard_events.last
        if ev.ev_type == RETURN
          return ev.store_id
        end
        nil
      end
    
      def rent(customer)
        last = snowboard_events.last
        if last.ev_type == RETURN
          ev = SnowboardEvent.new(
               {:ev_type => RENT,
                :snowboard_id => id,
                :customer_id => customer.id
                :store_id => nil })
          ev.save
        end
      end
    
      def return_to(store)
        last = snowboard_events.last
        if last.ev_type != RETURN
          # Force customer to be same as last one
          ev = SnowboardEvent.new(
               {:ev_type => RETURN,
                :snowboard_id => id,
                :customer_id => last.customer.id
                :store_id => store.id})
          ev.save
        end
      end
    end
    

    顾客也会有同样的感受 has_many :snowboard_events .

    检查滑雪板或客户历史记录,只需使用 Snowboard.snowboard_events Customer.snowboard_events 创建于 这些事件的性质。我不认为使用Observer是必要的或相关的。

    注意:上面的代码没有经过测试,也不是完美的,只是为了得到这个想法:)