私はタスクマネージャーを作成しており、「完了」のブール属性を持っています。「finished」を true に切り替えたときに「finished_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' WHERE "タスク"."id" = 1"
だから私は同じ方法を使用しますが、それはいくつかの理由でrspecでのみ機能します...
最新のレールと最新の仕様を使用します (rc やベータ版ではありません)。
解決
編集する必要はありませんでした。ヒントをくれた@Frederick Cheungに感謝します。「write_attribute」よりも「self[:attr]」の方が好きだということに気付きました。見栄えが良くなりました。
def finished=(value)
self[:finished] = value
self[:finished_at] = (self.finished? ? Time.now.utc : nil)
end