Rails rental store implementation: how to track inventory status over time?

Say you are introducing a rails app for a snowboard rental store.

This snowboard can be in one of three states:

  • for service
  • Available at Store X
  • on credit to client Y

The company should be able to view rental history for

  • concrete snowboard
  • specific client

The rental history should include temporary data (for example, Sally rented snowboard 0123 from December 1, 2009 to December 3, 2009).

How would you design your model? You will have a snowboard table with 4 columns (id, state, customer, store) and copy the rows from this table along with the timestamp into the snowboard_history table every time a state changes?

Thanks!

(: , , .)

+3
2

, . . , , .

act_as_state_machine acts_as_audited

AASM . , .

, ___ .

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    

, 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
+9

Snowboard, Customer Store.

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)

, / , (, , ).

SnowboardEvent ( SnowboardHistory, , ) , :

  • ev_type ( 0 RETURN, 1 , 2 ...)
  • snowboard_id ( null)
  • 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. " " - created_at . , Observer .

: , , :)

+2

Source: https://habr.com/ru/post/1722969/


All Articles