我正在Rails中建立一个具有特定销售模型的商店。我需要允许用户每30天只创建3个订单。因此,如果用户创建一个订单,那么在30天内允许另外两个订单。 30天柜台应该在创建第一个订单时开始。 30天后重置计数器进行订购,用户再次能够创建3个订单......
现在,一旦创建了每个订单,它就会保存到数据库中,并且可以获得无限量的订单。
我不确定如何实现这一目标并限制current_user每30天创建超过3个订单。 我还想显示一个错误通知,即每30天不可能超过3个订单。
我有产品,订单,用户,每个都有模型和控制器。订单也能够具有许多状态,如“已完成”,“处理”等。 我正在使用标准的Devise身份验证。
order_items_controller:
def create
@order = current_order
@order_item = @order.order_items.new(order_item_params)
@order.user_id = current_user.id
@order.save
session[:order_id] = @order.id
respond_to do |format|
format.js { flash[:notice] = "ORDER HAS BEEN CREATED." }
end
end
private
def order_item_params
params.require(:order_item).permit(:quantity, :product_id, :user_id)
end
end
Order.rb
class Order < ActiveRecord::Base
belongs_to :order_status
has_many :order_items
before_create :set_order_status
before_save :update_subtotal
def subtotal
order_items.collect { |oi| oi.valid? ? (oi.quantity * oi.unit_price) : 0 }.sum
end
private
def set_order_status
self.order_status_id = 1
end
def update_subtotal
self[:subtotal] = subtotal
end
end
user.rb
class User < ActiveRecord::Base
has_many :identities, dependent: :destroy
has_many :order
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :omniauthable, :invitable, :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable
end
order_item.rb:
class OrderItem < ActiveRecord::Base
belongs_to :product
belongs_to :order
validates :quantity, presence: true, numericality: { only_integer: true, greater_than: 0 }
validate :product_present
validate :order_present
before_save :finalize
def unit_price
if persisted?
self[:unit_price]
else
product.price
end
end
def total_price
unit_price * quantity
end
private
def product_present
if product.nil?
errors.add(:product, "is not valid or is not active.")
end
end
def order_present
if order.nil?
errors.add(:order, "is not a valid order.")
end
end
def finalize
self[:unit_price] = unit_price
self[:total_price] = quantity * self[:unit_price]
end
end
order_status.rb
class OrderStatus < ActiveRecord::Base
has_many :orders
belongs_to :user
end
每个订单商品的form_view.html.erb
<%= form_for OrderItem.new, remote: true do |f| %>
<div class="input-group">
<%= f.hidden_field :quantity, value: 1, min: 1 %>
<div class="input-group-btn">
<%= f.hidden_field :product_id, value: product.id %>
<%= f.submit "Add to Cart", data: { confirm: 'Are you sure that you want to order this item for current cycle?'}, class: "btn btn-default black-background white" %>
</div>
</div>
<% end %>
</div>
答案 0 :(得分:0)
其中一种可能的解决方案是在您的订单中添加一个布尔标志,以表明它是“起始链”订单(一个开始30天计数器的订单)。将此标志设置为true的订单将开始30天计数器,而带有false标志的订单将是“常规”订单。
然后在创建时(在last_30_days_orders = Order
.where("user_id = ? AND created_at > ?", current_user.id, DateTime.now - 30)
if last_30_days_orders.any? {|order| order.starting_chain? }
# there was a starting chain order in last 30 days
if last_30_days_orders.length >= 3
# reject new order - already 3 orders in chain
...
else
# there is a chain and it has less then 3 orders yet - ready to go
@order.starting_chain = false
# proceed with saving
...
end
else # no orders within 30 days, or starting_chain order was more then 30 days ago
# => new period starts
@order.starting_chain = true
# proceed with saving
...
end
中)你做这样的事情:
import queue
import socket
import os
class PollableQueue(queue.Queue):
def __init__(self):
super().__init__()
# Create a pair of connected sockets
if os.name == 'posix':
self._putsocket, self._getsocket = socket.socketpair()
else:
# Compatibility on non-POSIX systems
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 0))
server.listen(1)
self._putsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._putsocket.connect(server.getsockname())
self._getsocket, _ = server.accept()
server.close()
def fileno(self):
return self._getsocket.fileno()
def put(self, item):
super().put(item)
self._putsocket.send(b'x')
def get(self):
self._getsocket.recv(1)
return super().get()