我为咖啡店建立奖励系统。基本上,客户可以注册一年的订阅。现在,当他们注册active
属性时,切换为true。我正在尝试编写一个方法,在一年过后将属性切换为false。我现在有一个方法,我想使用,但我不知道在哪里使用它?我也有一个失败的测试。为了清楚起见,我将展示我当前的代码。
def create
@subscriber = Subscriber.new(subscriber_params)
if @subscriber.save
@subscriber.touch(:subscription_date)
@subscriber.update(active: true)
SubscriberMailer.welcome_subscriber(@subscriber).deliver_now
flash[:notice] = "Subscriber Has Been Successfully Created"
redirect_to new_subscriber_path(:subscriber)
else
render "new"
end
end
def not_active(subscriber)
if subscription_date < 1.year.ago
self.update(active: false)
end
end
it "sets active to false after a year" do
subscriber = create(:subscriber)
subscriber.update(active: true)
Time.now + 366.days
expect(subscriber.active).to eq(false)
end
所以希望这个想法很清楚。我只想更新为active:false如果用户是在一年前创建的。
答案 0 :(得分:2)
您必须运行not_active
方法才能使方法生效。该方法无法知道当前的日期和更新订户,除非它实际运行。我同意matt,你可能会在sidekiq job每日update!运行这种方法,对所有订阅了一年或更久以前并且处于活动状态的订阅者(你可以为此编写一个范围)。这样,您可以调用not_active
方法并适当地设置每个订阅者的活动,或将其写为订阅者类方法并将其应用于范围的结果。在测试not_active
方法本身的情况下,您需要做的就是调用它并测试结果。我也不清楚为什么not_active
方法将订阅者作为arg,似乎从订阅者实例中调用它会更有意义。这不是什么事情已经发生了吗?我个人会称这种方法为deactivate!
,因为它正在进行更改。 not_active
类似的声音会返回布尔值或非活动订阅者。我还建议使用更新!而不是not_active
中的更新。如果更新失败,rspec mocks将引发错误。添加到time.now确实会改变时间。如果需要,您可以使用{{3}}伪造当前时间。无论如何,这是not_active
测试的样子:
it "sets active to false after a year" do
subscriber = Subscriber.create(subscription_date: (1.year.ago - 1.day), active: true)
#changed not_active to deactivate, called from instance instead of passing in subscriber
subscriber.deactivate!
expect(subscriber.active?).to eq(false)
end
您也可以为其他案例编写测试
it "does not deactivate a recent subscriber" do
subscriber = Subscriber.create(subscription_date: Date.today, active: true)
subscriber.deactivate!
expect(subscriber.active?).to eq(true)
end
答案 1 :(得分:1)
对此的一个简单解决方案是使用cron。有一个与cron接口的rubygem,称为whenever。设置简单,文档齐全。
使用服务器上的cron设置,您可以创建某种类方法,该方法将遍历Subscribers
,并调用not_active
方法。
顺便说一句,如果在not_active
模型中定义Subscriber
方法,则您不需要将订阅者作为参数传递,因为self将隐式设置为订阅者。
代码最终会看起来像:
在subscriber.rb
中def self.set_subscribers_to_inactive
find_each(active: false) do |subscriber|
subscriber.inactive!
end
end
def inactive!
update(active: false) if subscription_date < 1.year.ago
end
在schedule.rb
中every 1.day do
runner "Subscriber.set_subscribers_to_inactive"
end
如上所述,您的测试实际上并未调用not_active
方法。
it "sets active to false after a year" do
last_year = DateTime.current - 366.days
subscriber = create(:subscriber, active: true, subscription_date: last_year)
subscriber.inactive!
expect(subscriber.active).to eq false
end
答案 2 :(得分:0)
查看cron
和whenever
gem,它位于cron
之上。您只需要编写一个超级简单的脚本,它将从DB中提取数据并进行更新。
解决问题的另一种方法是不更新任何内容。您只需要*_expires_at
列并检查其值是否小于当前日期。
这是非常灵活的方法,因为通过使用activation_expires_at
列,您可以实现#active?
方法和.active
范围,以便仅选择具有有效订阅的用户。