Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow created_at and updated_at to be set on create #8

Closed
qrush opened this issue Jun 4, 2009 · 2 comments
Closed

Allow created_at and updated_at to be set on create #8

qrush opened this issue Jun 4, 2009 · 2 comments
Labels

Comments

@qrush
Copy link
Contributor

qrush commented Jun 4, 2009

Reported by Eric Mill

In ActiveRecord, you can't set the created_at or updated_at timestamps through the use of #save. At best, you can update the created_at timestamp by using #update_attribute in a second command after the object has been created, but you can't get away with even that for updated_at -- you have to execute SQL.

Since setting created_at and updated_at timestamps are often useful in test environments, I'm asking that FactoryGirl have a special case for created_at and updated_at that lets them be overridden.

The following should work as expected:

user = Factory :user, :created_at => 2.days.ago, :updated_at => 1.day.ago
user.created_at #=> 2 days ago
user.updated_at #=> 1 day ago

user = Factory.build :user, :created_at => 2.days.ago, :updated_at => 1.day.ago
user.save
user.created_at #=> 2 days ago
user.updated_at #=> 1 day ago

The latter seems much more difficult to implement than the former -- the only way I could think to do it would be to instance_eval an after_create callback on the built object, to make sure that it'd get updated appropriately down the line. However, I'd be happy even if only the first form works.

Similarly, the following should work as expected:

Factory.define :user do |u|
  u.created_at {Factory.next :user_created_at}
end

Factory.sequence(:user_created_at) {|i| i.days.ago}

I'm interested in hearing people's opinions on this.

@vandrijevik
Copy link

Hey Eric,

Instead of what you are proposing above, I think it's better to fake Time.now to whichever time you want in your tests, and then create objects like you normally do. That way, ActiveRecord still does the magic timestamping for you, and you have control of whether you fake the timestamps or not per-test.

Since this is a common patter, I've made a gem that makes it easy to do this: https://github.com/vandrijevik/with_time_frozen_at/

With that, in your test you'd write:

with_time_frozen_at(2.days.ago) do |fake_time|
  Factory(:user)
end

And your user's timestamps would be set to two days ago.

I hope this helps answer your question.

@qrush
Copy link
Contributor Author

qrush commented Aug 25, 2009

I think using Timecop or vandrijevik's plugin has become the standard of doing this. Closing this issue out.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants