我正在制作一个任务管理器,并有一个“完成”的布尔属性。当我将“完成”切换为真时,我试图覆盖设置器以实现“完成_at”日期。
但我得到了一些好坏参半的结果。它在浏览器中不起作用,但在我的 rspec 测试中起作用。
请帮帮我。
class TasksController < ApplicationController
# ...
def update
# ..
if @task.update_attributes(params[:task]) # where params[:task][:finished] is true
# ...
end
class Task < ActiveRecord::Base
#...
def finished=(f)
write_attribute :finished, f
write_attribute :finished_at, f == true ? DateTime.now : nil
end
end
# and in rspec i have
describe "when marked as finished" do
before { @task.update_attributes(finished: true) }
its(:finished_at) { should_not be_nil }
its(:finished_at) { should > (DateTime.now - 1.minute) }
describe "and then marked as unfinished" do
before { @task.update_attributes(finished: false) }
its(:finished_at) { should be_nil }
end
end
在浏览器中它执行 "UPDATE "tasks" SET "finished" = 't', "updated_at" = '2012-10-02 18:55:07.220361' WHERE "tasks"."id" = 17"
在 Rails 控制台中,我使用 update_attributes 得到了相同的结果。
但是在带有 update_attributes 的 rspec 中,我得到 "UPDATE "tasks" SET "finished" = 't', "finished_at" = '2012-10-02 18:36:47.725813', "updated_at" = '2012-10-02 18: 36:51.607143'在哪里“任务”。“id”= 1“
所以我使用相同的方法,但它只在 rspec 中工作了一些 reson...
使用最新的轨道和最新的规范(不是任何 rc 或 beta)。
解决方案
我不需要编辑。感谢@Frederick Cheung 的提示。我确实注意到我确实喜欢“self [:attr]”而不是“write_attribute”。看起来更好。
def finished=(value)
self[:finished] = value
self[:finished_at] = (self.finished? ? Time.now.utc : nil)
end