我如何在Rails中实现卖家可以在24小时内取消或接受的出价,或者交易被取消
How can I implement in Rails bid offers that sellers can cancel or accept within 24hrs or transaction is cancelled?
我在rails的一个市场上工作,该市场允许买家向卖家出价购买物品。卖家可以取消或接受出价,但只有24小时的时间窗口,否则出价到期,交易被取消。用户既可以是买方,也可以是卖方。
我有一个订单模型来表示每一笔交易。
Class Order < ActiveRecord::Base
belongs_to :seller, class_name: "User"
belongs_to :buyer, class_name: "User"
belongs_to :listing
end
在我的预订控制器上,类订单控制器<应用程序控制器before_action:authenticate_user!
def create
@order = Order.new(order_params)
@seller = @order.listing.user
@order.buyer_id = current_user.id
@order.seller_id = @seller.id
@bidding_fee = @order.bidding_fee
end
我想区分买家取消和卖家取消,因为如果卖家取消了对物品的出价,买家不支付出价费,但如果买家取消了他所做的订单,他将被收取出价费。如何执行投标交易。最困难的部分是在rails中创建一个计时器,向卖家显示还剩多少时间,例如在出价到期前4小时12分钟,如果没有回应,则在24小时后取消出价,特别是要记住不同的客户端时区,这些时区可能与订单的created_at时间相隔数小时。我还需要将订单状态显示为挂起、取消或接受,这排除了布尔功能,因为这会创建三种可能的状态。在这些问题上提供任何帮助都将不胜感激。
您实际上并不需要计时器。你只需要时间,直到出价有效。我想你会有某种Bit
型号。当expires_at
列中的出价到期时,买方商店创建比特时:
class Bid < ActiveRecord::Base
before_create :set_expired_at
private
def set_expired_at
self.expired_at = Time.current + 24.hour
end
end
这允许您将expired?
方法添加到同一类中,您可以在视图中使用该方法来决定是否仍要列出报价:
def expired?
expired_at < Time.current
end
或者你可以添加一个作用域来只加载未过期的位:
scope :unexpired, -> { where('expired_at < ?', Time.current) }
如果报价挂起或被排除,则可以在数据库中实现为简单的accepted
布尔值。这导致了以下status
方法:
def status
if accepted?
'accepted'
else
expired? ? 'expired' : 'pending'
end
end
由于所有这些方法都取决于当前时间,因此不需要外部计时器、cron作业或后台作业。模型本身总是能够返回当前状态。
您可能已经注意到,在bids
表中(我假设表名)有一个名为created_at
的字段。您可以将其用作start-time
指示器。
在bids
页面中,您可以显示对seller
的所有出价。要么你可以
- 仅显示有效投标(
bids.where('bids.created_at > ?', 24.hours.ago)
) - 或者,显示所有
bids
,但禁用在24 Hours
之前创建的出价
更好的方法是跟踪具有status
属性的投标状态。要在24小时后使bid
无效,可以使用sidekiq
、resque
等后台处理器。
例如:使用Sidekiq
BidInvalidator.perform_in(24.hours, 'mike', 1)
BidInvalidator.perform_at(24.hours.from_now, 'mike', 1)
更新
你知道如何根据数据库上created_at时间戳的时区帐户某些用户可能会在created_at时间之前提出报价,如果他们住在阿拉斯加6小时后?
ActiveRecord以UTC时间存储所有日期时间,这样开发人员就可以将其转换为您喜欢的任何时区。
您需要根据用户的时区设置TimeXone
。您可以将timezone offset
存储在浏览器cookie中,并在服务器端获得offset
来计算timezone
。
$(document).ready(function(){
if(!($.cookie('time_zone'))) {
current_time = new Date();
expired_after_days = 365;
$.cookie('time_zone', current_time.getTimezoneOffset(), { path: '/', expires: expired_after_days } );
// Here expired_after_days represents the number of days the cookies will store the info
}
})
在application_controller
中,您可以
# setting the time zone with the current time zone offset
before_filter :set_time_zone
def set_time_zone
time_zone_offset = cookies[:time_zone].to_i
Time.zone = ActiveSupport::TimeZone[-time_zone_offset.minutes]
end
注意:Time.zone
是线程安全的。
现在您需要使用DateTime.current
来代替DateTime.now
它是否提供了创建一个检查状态属性的频率稍微高一点,比如每十分钟一次。如果投标被立即取消我不想在24小时前等待通知买方投标被取消
要在特定时间点执行任务,可以使用Whenever gem
创建cronjobs
您可以使用delayed_job
、sidekiq
或resque
或类似工具来安排在创建出价后立即调用您的函数。当24小时结束时,当函数get被调用时,你可以在那里检查它是否被接受。
- 如何在angularJS中编辑时,如果DB中的值为true,则设置复选框,如果值为false,则取消选中复选框
- jquery点击函数select&取消选择
- 使用Jquery选择或取消选择ListView中的所有复选框
- 使用jquery选中/取消选中单个复选框
- 使用javascript取消隐藏和隐藏表单中的某些元素
- 如何销毁/删除/取消绑定SnapSVG.js
- 滚动然后捕捉到顶部而不是取消捕捉
- 取消绑定主干视图事件
- 如何取消object.prototypes javascript的一个函数
- 使用javascript在页面加载时取消选中所有复选框
- 阻止浏览器对keydown事件作出反应,但不取消该事件
- jquery选中并取消选中所有操作
- IE11中的第二个调用取消了第一个Fetch API调用
- 如何知道使用socket.io订阅/取消订阅频道
- 如何在单击“提交”按钮时为“新建”窗口编写JavaScript,用“确定”和“取消”显示注册信息
- 如何在javascript中取消选择文本框
- 如何从另一个处理程序内部取消JavaScript事件处理程序函数的执行
- (取消)使用单独的复选框激活复选框列表
- 如何取消选择所选选项并将JqueryMobile中选择的值刷新为1st
- 我如何在Rails中实现卖家可以在24小时内取消或接受的出价,或者交易被取消