Fix and implement supplier counters
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 573 B |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 31 KiB |
@@ -44,6 +44,10 @@ class Quser
|
||||
else if(e.event == 'new_order')
|
||||
$('#active-list-table tbody').append @mustache('#active-list-order-template', new Order(e.data.order))
|
||||
$('.list-total-amount').html(currency(e.data.total_amount))
|
||||
else if(e.event == 'orders_in_process_count')
|
||||
$('.supplier-orders-in-process-count').text(e.data.count || 0)
|
||||
else if(e.event == 'orders_placed_count')
|
||||
$('.supplier-orders-placed-count').text(e.data.count || 0)
|
||||
console.log(e)
|
||||
false
|
||||
ensure_json: (res)->
|
||||
@@ -97,6 +101,9 @@ class Quser
|
||||
|
||||
$('.table-number').text(response.table_number) if response.table_number
|
||||
$('.supplier-name').text(response.supplier_name) if response.supplier_name
|
||||
$('.supplier-orders-placed-count').text(response.supplier_orders_placed_count || 0)
|
||||
$('.supplier-orders-in-process-count').text(response.supplier_orders_in_process_count || 0)
|
||||
|
||||
|
||||
if response.not_present || response.list_active == false then $('.home-link').removeClass('active') else $('.home-link').addClass('active')
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
.supplier-info-row
|
||||
clear: right
|
||||
.supplier-orders-in-process-count
|
||||
background-image: image-url('icons/order-check.png')
|
||||
padding-left: 20px
|
||||
padding-right: 6px
|
||||
.supplier-orders-delivered-count
|
||||
background-image: image-url('icons/order-doublecheck.png')
|
||||
padding-left: 28px
|
||||
.supplier-orders-placed-count
|
||||
background-image: image-url('icons/orders-queue.png')
|
||||
padding-left: 22px
|
||||
padding-right: 6px
|
||||
//padding-top: 4px
|
||||
//padding-top: 4px
|
||||
.top-button-bar
|
||||
.counter
|
||||
display: inline
|
||||
background-repeat: no-repeat
|
||||
background-position: left center
|
||||
@@ -4,3 +4,6 @@
|
||||
li
|
||||
list-style: none
|
||||
margin-bottom: 8px
|
||||
.qr-image
|
||||
background-color: white
|
||||
display: block
|
||||
|
||||
@@ -23,8 +23,18 @@ class DashboardController < ApplicationController
|
||||
size = RQRCode.minimum_qr_size_from_string(code)
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.svg { render :qrcode => code, :level => :l, :unit => 10, table_number: @table.number, qcontainer: true }
|
||||
format.png { render qrcode: code, level: :l, table_number: @table.number, qcontainer: true }
|
||||
format.svg { render qrcode: code, level: :l, unit: 10, table_number: @table.number, qcontainer: true }
|
||||
format.png do
|
||||
#render qrcode: code, level: :l, table_number: @table.number, qcontainer: true
|
||||
size = RQRCode.minimum_qr_size_from_string(code)
|
||||
level = :l
|
||||
qrcode = RQRCode::QRCode.new(code, size: size, level: level)
|
||||
svg = RQRCode::Renderers::SVG::render(qrcode)
|
||||
svg_file = Tempfile.new(['table_qr', '.svg']){|f| f.puts svg}
|
||||
png_target = svg_file.path.sub /svg$/, 'png'
|
||||
|
||||
render nothing: true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ class UserController < ApplicationController
|
||||
end
|
||||
format.json do
|
||||
render json: js_alert(t('messages.the_list_has_been_closed')) and return unless list.present?
|
||||
render json: list.with_orders_and_join_requests_as_json.merge(supplier_name: list.supplier.name)
|
||||
render json: list.with_orders_and_join_requests_and_supplier_info_as_json
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+11
-3
@@ -270,7 +270,7 @@ class List
|
||||
return false unless user
|
||||
order = Order.create list: self, supplier: supplier, user: user, section_id: section_id
|
||||
return unless order.id
|
||||
orders_in_process_count = supplier.increment_orders_in_process_count!
|
||||
orders_placed_count = supplier.increment_orders_placed_count!
|
||||
loaded_products = self.class.database.load_document products.keys
|
||||
products.each do |product_id, quantity|
|
||||
quantity = quantity.to_i
|
||||
@@ -281,11 +281,11 @@ class List
|
||||
save
|
||||
for user_id in user_ids
|
||||
broadcast_user user_id, 'new_order', order: order.with_products_as_json, total_amount: price
|
||||
broadcast_user user_id, 'orders_in_process_count', count: orders_in_process_count
|
||||
broadcast_user user_id, 'orders_placed_count', count: orders_placed_count
|
||||
end
|
||||
broadcast_supplier supplier.id, 'list_update', active_model_serializer.new(self).as_json
|
||||
broadcast_supplier supplier.id, 'new_order', OrderSerializer.new(order)
|
||||
broadcast_supplier supplier.id, 'orders_in_process_count', count: orders_in_process_count
|
||||
broadcast_supplier supplier.id, 'orders_placed_count', count: orders_placed_count
|
||||
order
|
||||
end
|
||||
|
||||
@@ -323,6 +323,14 @@ class List
|
||||
@with_orders_and_join_requests_as_json = with_orders_as_json.merge(join_requests_as_json)
|
||||
end
|
||||
|
||||
def with_orders_and_join_requests_and_supplier_info_as_json
|
||||
with_orders_and_join_requests_as_json.merge(
|
||||
supplier_name: supplier.name,
|
||||
supplier_orders_in_process_count: supplier.orders_in_process_count,
|
||||
supplier_orders_placed_count: supplier.orders_placed_count
|
||||
)
|
||||
end
|
||||
|
||||
def has_active_orders?
|
||||
Order.count_active_for_supplier_and_list(supplier_id, id) > 0
|
||||
end
|
||||
|
||||
+7
-7
@@ -78,29 +78,29 @@ class Order
|
||||
def is_being_processed!
|
||||
self.state = 'active'
|
||||
if save
|
||||
orders_in_process_count = supplier.decrement_orders_in_process_count!
|
||||
orders_delivered_count = supplier.increment_orders_delivered_count!
|
||||
orders_in_process_count = supplier.increment_orders_in_process_count!
|
||||
orders_placed_count = supplier.decrement_orders_placed_count!
|
||||
for user_id in list.user_ids
|
||||
broadcast_user user_id, 'order_being_processed', id: id, list_id: list_id
|
||||
broadcast_user user_id, 'orders_in_process_count', count: orders_in_process_count
|
||||
broadcast_user user_id, 'orders_delivered_count', count: orders_delivered_count
|
||||
broadcast_user user_id, 'orders_placed_count', count: orders_placed_count
|
||||
end
|
||||
broadcast_supplier supplier_id, 'order_being_processed', id: id, list_id: list_id
|
||||
broadcast_supplier supplier_id, 'orders_in_process_count', count: orders_in_process_count
|
||||
broadcast_supplier supplier_id, 'orders_delivered_count', count: orders_delivered_count
|
||||
broadcast_supplier supplier_id, 'orders_placed_count', count: orders_placed_count
|
||||
end
|
||||
end
|
||||
|
||||
def is_delivered!
|
||||
self.state = 'delivered'
|
||||
if save
|
||||
orders_delivered_count = supplier.decrement_orders_delivered_count!
|
||||
orders_in_process_count = supplier.decrement_orders_in_process_count!
|
||||
for user_id in list.user_ids
|
||||
broadcast_user user_id, 'order_being_delivered', id: id, list_id: list_id
|
||||
broadcast_user user_id, 'orders_delivered_count', count: orders_delivered_count
|
||||
broadcast_user user_id, 'orders_in_process_count', count: orders_in_process_count
|
||||
end
|
||||
broadcast_supplier supplier_id, 'order_being_delivered', id: id, list_id: list_id
|
||||
broadcast_supplier supplier_id, 'orders_delivered_count', count: orders_delivered_count
|
||||
broadcast_supplier supplier_id, 'orders_in_process_count', count: orders_in_process_count
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
+15
-12
@@ -116,6 +116,9 @@ class Supplier
|
||||
end
|
||||
|
||||
def self.reset_counters!
|
||||
|
||||
Qwaiter::Couchbase.design_doc('supplier').counters(reduce: false).each{|counter| Qwaiter::Counter.set counter.key, 0}
|
||||
|
||||
spec = Order.by_supplier_id_and_state(reduce: true, group_level: 2)
|
||||
reset_order_counters_with_spec spec
|
||||
end
|
||||
@@ -137,8 +140,8 @@ class Supplier
|
||||
Array.wrap(results['rows']).each do |result|
|
||||
supplier_id, state = result['key']
|
||||
case state
|
||||
when 'placed' then Qwaiter::Counter.set "supplier:#{supplier_id}:orders_in_process", result['value']
|
||||
when 'active' then Qwaiter::Counter.set "supplier:#{supplier_id}:orders_delivered", result['value']
|
||||
when 'placed' then Qwaiter::Counter.set "supplier_counter:#{supplier_id}:orders_placed", result['value']
|
||||
when 'active' then Qwaiter::Counter.set "supplier_counter:#{supplier_id}:orders_in_process", result['value']
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -168,31 +171,31 @@ class Supplier
|
||||
end
|
||||
|
||||
def increment_orders_in_process_count!
|
||||
Qwaiter::Counter.incr "supplier:#{id}:orders_in_process"
|
||||
Qwaiter::Counter.incr "supplier_counter:#{id}:orders_in_process"
|
||||
end
|
||||
|
||||
def increment_orders_delivered_count!
|
||||
Qwaiter::Counter.incr "supplier:#{id}:orders_delivered"
|
||||
def increment_orders_placed_count!
|
||||
Qwaiter::Counter.incr "supplier_counter:#{id}:orders_placed"
|
||||
end
|
||||
|
||||
def decrement_orders_in_process_count!
|
||||
Qwaiter::Counter.decr "supplier:#{id}:orders_in_process"
|
||||
Qwaiter::Counter.decr "supplier_counter:#{id}:orders_in_process"
|
||||
end
|
||||
|
||||
def decrement_orders_delivered_count!
|
||||
Qwaiter::Counter.decr "supplier:#{id}:orders_delivered"
|
||||
def decrement_orders_placed_count!
|
||||
Qwaiter::Counter.decr "supplier_counter:#{id}:orders_placed"
|
||||
end
|
||||
|
||||
def orders_in_process_count
|
||||
Qwaiter::Counter.get "supplier:#{id}:orders_in_process"
|
||||
Qwaiter::Counter.get "supplier_counter:#{id}:orders_in_process"
|
||||
end
|
||||
|
||||
def orders_delivered_count
|
||||
Qwaiter::Counter.get "supplier:#{id}:orders_delivered"
|
||||
def orders_placed_count
|
||||
Qwaiter::Counter.get "supplier_counter:#{id}:orders_placed"
|
||||
end
|
||||
|
||||
def active_order_count
|
||||
orders_in_process_count + orders_delivered_count
|
||||
orders_in_process_count + orders_placed_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.page-header= title 'Select Qr code'
|
||||
ul#qr-list
|
||||
- for table in @tables
|
||||
li= link_to_function image_tag(url_for(table_qr_image_path(table_id: table.id, format: :png))), %|Quser.actions_for_table({table_id: '#{table.id}'})|
|
||||
li= link_to_function image_tag(url_for(table_qr_image_path(table_id: table.id, format: :svg)), class: 'qr-image'), %|Quser.actions_for_table({table_id: '#{table.id}'})|
|
||||
|
||||
@@ -28,7 +28,7 @@ html lang="en"
|
||||
ul.nav.pull-right
|
||||
li.dropdown
|
||||
a.dropdown-toggle href="#" data-toggle="dropdown"
|
||||
= current_supplier.email
|
||||
= current_supplier.name.presence || current_supplier.email
|
||||
b.caret
|
||||
ul.dropdown-menu
|
||||
- if current_supplier.open?
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
= top_bar title: 'active_list.title' do
|
||||
.pull-right
|
||||
.table-number
|
||||
.supplier-name
|
||||
.supplier-info-row
|
||||
.table-number
|
||||
.supplier-name
|
||||
.supplier-info-row
|
||||
.counter.supplier-orders-placed-count
|
||||
.counter.supplier-orders-in-process-count
|
||||
.action-buttons
|
||||
= link_to content_tag(:span, t('helpers.links.place_order')), user_list_products_path, class: ['user-top-button'], id: 'place-order-on-list'
|
||||
span#list-needs-payment-button.user-top-button
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
= top_bar title: 'show_products.title' do
|
||||
.pull-right
|
||||
.table-number
|
||||
.supplier-name
|
||||
.supplier-info-row
|
||||
.table-number
|
||||
.supplier-name
|
||||
.supplier-info-row
|
||||
.counter.supplier-orders-placed-count
|
||||
.counter.supplier-orders-in-process-count
|
||||
.action-buttons
|
||||
= link_to user_active_list_path, class: ['user-top-button'], id: 'show-active-list' do
|
||||
span= t('helpers.links.show_active_list', list: List.model_name.human)
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
= top_bar title: 'show_products.title' do
|
||||
.pull-right
|
||||
.table-number
|
||||
.supplier-name
|
||||
.supplier-info-row
|
||||
.table-number
|
||||
.supplier-name
|
||||
.supplier-info-row
|
||||
.counter.supplier-orders-placed-count
|
||||
.counter.supplier-orders-in-process-count
|
||||
.well
|
||||
table#products-table.table.table-hover
|
||||
tbody
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"_id": "_design/supplier",
|
||||
"language": "javascript",
|
||||
"views": {
|
||||
"counters": {
|
||||
"map": "function(doc, meta){if(meta.id.match(/^supplier_counter/)) emit(meta.id, doc)}",
|
||||
"reduce": "_sum"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ module Qwaiter
|
||||
autoload :Serializer
|
||||
autoload :Counter
|
||||
autoload :Broadcaster
|
||||
autoload :Couchbase
|
||||
|
||||
def self.broadcast_user(uid, event, data)
|
||||
message = {channel: "/user/#{uid}", data: {event: event, data: data}}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
module Qwaiter
|
||||
module Couchbase
|
||||
def self.connection
|
||||
$cb
|
||||
end
|
||||
|
||||
def self.load_design_docs!
|
||||
Dir.glob(Rails.root.join('config/couchbase/design_docs', "*.json")).each do |design_doc|
|
||||
connection.save_design_doc File.open(design_doc)
|
||||
end
|
||||
end
|
||||
|
||||
def self.design_doc(name)
|
||||
connection.design_docs[name]
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -8,15 +8,16 @@ module Qwaiter
|
||||
end
|
||||
|
||||
def self.get(key)
|
||||
connection.get(key).to_i
|
||||
connection.get(key, quiet: true).to_i
|
||||
end
|
||||
|
||||
def self.incr(*args)
|
||||
connection.incr(*args)
|
||||
def self.incr(key, options = {})
|
||||
options[:initial] ||= 0
|
||||
connection.incr(key, options)
|
||||
end
|
||||
|
||||
def self.decr(*args)
|
||||
connection.decr(*args)
|
||||
def self.decr(key, options = {})
|
||||
connection.decr(key, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,7 +16,7 @@ module RQRCode
|
||||
|
||||
qrcode = RQRCode::QRCode.new(string, :size => size, :level => level)
|
||||
svg = RQRCode::Renderers::SVG::render(qrcode, options)
|
||||
|
||||
|
||||
data = \
|
||||
if format == :png
|
||||
image = MiniMagick::Image.read(svg) { |i| i.format "svg" }
|
||||
|
||||
@@ -138,11 +138,11 @@ describe List do
|
||||
|
||||
expect{
|
||||
list.place_order(user, product.id => 3)
|
||||
}.to broadcast_to_user(user.id).message('orders_in_process_count').with(count: 2)
|
||||
}.to broadcast_to_user(user.id).message('orders_placed_count').with(count: 2)
|
||||
|
||||
expect{
|
||||
list.place_order(user, product.id => 5)
|
||||
}.to broadcast_to_supplier(supplier.id).message('orders_in_process_count').with(count: 3)
|
||||
}.to broadcast_to_supplier(supplier.id).message('orders_placed_count').with(count: 3)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
+14
-14
@@ -47,24 +47,24 @@ describe Order do
|
||||
describe 'counters' do
|
||||
before do
|
||||
# hack some initial values
|
||||
Qwaiter::Counter.set "supplier:#{supplier.id}:orders_in_process", 7
|
||||
Qwaiter::Counter.set "supplier:#{supplier.id}:orders_delivered", 9
|
||||
Qwaiter::Counter.set "supplier_counter:#{supplier.id}:orders_placed", 11
|
||||
Qwaiter::Counter.set "supplier_counter:#{supplier.id}:orders_in_process", 7
|
||||
end
|
||||
|
||||
it 'reduces the orders_in_process count and communicates it to user' do
|
||||
expect{ order.is_being_processed! }.to broadcast_to_user(user.id).message( 'orders_in_process_count' ).with(count: 6)
|
||||
it 'reduces the orders_placed count and communicates it to user' do
|
||||
expect{ order.is_being_processed! }.to broadcast_to_user(user.id).message( 'orders_placed_count' ).with(count: 10)
|
||||
end
|
||||
|
||||
it 'increases the orders_delivered count and communicates it to user' do
|
||||
expect{ order.is_being_processed! }.to broadcast_to_user(user.id).message( 'orders_delivered_count' ).with(count: 10)
|
||||
it 'increases the orders_in_process count and communicates it to user' do
|
||||
expect{ order.is_being_processed! }.to broadcast_to_user(user.id).message( 'orders_in_process_count' ).with(count: 8)
|
||||
end
|
||||
|
||||
it 'reduces the orders_in_process count and communicates it to supplier' do
|
||||
expect{ order.is_being_processed! }.to broadcast_to_supplier(supplier.id).message( 'orders_in_process_count' ).with(count: 6)
|
||||
it 'reduces the orders_placed count and communicates it to supplier' do
|
||||
expect{ order.is_being_processed! }.to broadcast_to_supplier(supplier.id).message( 'orders_placed_count' ).with(count: 10)
|
||||
end
|
||||
|
||||
it 'increases the orders_in_process count and communicates it to supplier' do
|
||||
expect{ order.is_being_processed! }.to broadcast_to_supplier(supplier.id).message( 'orders_delivered_count' ).with(count: 10)
|
||||
expect{ order.is_being_processed! }.to broadcast_to_supplier(supplier.id).message( 'orders_in_process_count' ).with(count: 8)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -82,16 +82,16 @@ describe Order do
|
||||
describe 'counters' do
|
||||
before do
|
||||
# hack some initial values
|
||||
Qwaiter::Counter.set "supplier:#{supplier.id}:orders_in_process", 7
|
||||
Qwaiter::Counter.set "supplier:#{supplier.id}:orders_delivered", 9
|
||||
Qwaiter::Counter.set "supplier_counter:#{supplier.id}:orders_delivered", 11
|
||||
Qwaiter::Counter.set "supplier_counter:#{supplier.id}:orders_in_process", 7
|
||||
end
|
||||
|
||||
it 'decreases the orders_delivered count and communicates it to user' do
|
||||
expect{ order.is_delivered! }.to broadcast_to_user(user.id).message( 'orders_delivered_count' ).with(count: 8)
|
||||
it 'decreases the orders_in_process count and communicates it to user' do
|
||||
expect{ order.is_delivered! }.to broadcast_to_user(user.id).message( 'orders_in_process_count' ).with(count: 6)
|
||||
end
|
||||
|
||||
it 'decreases the orders_in_process count and communicates it to supplier' do
|
||||
expect{ order.is_delivered! }.to broadcast_to_supplier(supplier.id).message( 'orders_delivered_count' ).with(count: 8)
|
||||
expect{ order.is_delivered! }.to broadcast_to_supplier(supplier.id).message( 'orders_in_process_count' ).with(count: 6)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,9 +11,19 @@ describe Supplier do
|
||||
create_list :order, 7, :active, supplier: supplier1
|
||||
create_list :order, 3, :placed, supplier: supplier2
|
||||
Supplier.reset_counters!
|
||||
supplier1.orders_in_process_count.should == 2
|
||||
supplier1.orders_delivered_count.should == 7
|
||||
supplier2.orders_in_process_count.should == 3
|
||||
supplier1.orders_placed_count.should == 2
|
||||
supplier1.orders_in_process_count.should == 7
|
||||
supplier2.orders_placed_count.should == 3
|
||||
end
|
||||
|
||||
it 'cleans counter values if orders are no longer available' do
|
||||
# this spec should run on the couchbase database
|
||||
Qwaiter::Counter.connection = $cb
|
||||
supplier = create :supplier
|
||||
Qwaiter::Counter.set "supplier_counter:#{supplier.id}:orders_placed", 9
|
||||
supplier.orders_placed_count.should == 9
|
||||
Supplier.reset_counters!
|
||||
supplier.orders_placed_count.should == 0
|
||||
end
|
||||
end
|
||||
|
||||
@@ -23,8 +33,8 @@ describe Supplier do
|
||||
create_list :order, 5, :placed, supplier: supplier
|
||||
create_list :order, 9, :active, supplier: supplier
|
||||
supplier.reset_counters!
|
||||
supplier.orders_in_process_count.should == 5
|
||||
supplier.orders_delivered_count.should == 9
|
||||
supplier.orders_placed_count.should == 5
|
||||
supplier.orders_in_process_count.should == 9
|
||||
end
|
||||
end
|
||||
|
||||
@@ -83,10 +93,10 @@ describe Supplier do
|
||||
|
||||
end
|
||||
|
||||
describe '#decrement_orders_delivered_count!' do
|
||||
it 'decreases orders_delivered' do
|
||||
Qwaiter::Counter.set "supplier:#{supplier.id}:orders_delivered", 9
|
||||
supplier.decrement_orders_delivered_count!.should == 8
|
||||
describe '#decrement_orders_placed_count!' do
|
||||
it 'decreases orders_placed' do
|
||||
Qwaiter::Counter.set "supplier_counter:#{supplier.id}:orders_placed", 9
|
||||
supplier.decrement_orders_placed_count!.should == 8
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -46,6 +46,12 @@ end
|
||||
|
||||
# NOT THREADSAFE!!!!!! but good enough for testing since the real couchbase flush is slowwwwww....
|
||||
Qwaiter::Counter.connection = InMemoryQCounter.new
|
||||
class Couchbase::View
|
||||
alias :old_initialize :initialize
|
||||
def initialize(bucket, endpoint, params = {})
|
||||
old_initialize(bucket, endpoint, params.merge(stale: false))
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |config|
|
||||
# == Mock Framework
|
||||
@@ -100,6 +106,9 @@ RSpec.configure do |config|
|
||||
# examples within a transaction, remove the following line or assign false
|
||||
# instead of true.
|
||||
#config.use_transactional_fixtures = true
|
||||
config.before :suite do
|
||||
Qwaiter::Couchbase.load_design_docs!
|
||||
end
|
||||
|
||||
config.before :each do
|
||||
CouchPotato.couchrest_database.recreate!
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
class InMemoryQCounter
|
||||
STORE = {}
|
||||
|
||||
def get(key)
|
||||
def get(key, options = {})
|
||||
STORE[key]
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user