The timing of the automatically generated timestamps and attribute assignment in rails 2.3 security note 1 was interesting to me because I’d just spent a while really trying to get my head around attr_accessible and attr_protected and the best way to test their effects in an app I was working on. Although I intend to write about the testing separately, the conclusion I came to was that I wanted to test the behaviour (more specifically, I was interested in what I could/couldn’t assign) of my objects and not that I was specifically using attr_accessible or attr_protected.
Reading Alex’s post made me wonder whether the rails API ever guaranteed that the timestamps would be readonly: If that was the case then I can see arguments for not wanting to test the behaviour of your objects (because you’re essentially testing the framework itself). I couldn’t find any mention of whether they’d specifically be readonly so chose to do a bit of digging. I created a script that allowed me to, with relative ease, run tests against rails apps created with different versions of rails. Using this I was able to test the mass assignment of timestamps (created_at, created_on, updated_at and updated_on) against multiple versions of rails. The conclusion I came to (and I’d love for other people to replicate my experiment and prove/disprove my results) was that the created_at and created_on pair of attributes have always (at least as far back as rails 1.0.0) been assignable, while the updated_at and updated_on attributes have only recently become assignable. While digging I managed to find the lighthouse ticket (#1612) that requested the ability to set the updated_* timestamps and the rails commit that closed that ticket.
$ cd /path/to/code $ git clone git://github.com/rails/rails.git
mysql> CREATE DATABASE rails_timestamps_test; mysql> USE rails_timestamps_test; mysql> CREATE TABLE people (id INTEGER AUTO_INCREMENT, created_on DATE, created_at DATETIME, updated_on DATE, updated_at DATETIME, PRIMARY KEY (id));
$ cd /path/to/code $ svn co http://chrisroos.googlecode.com/svn/trunk/scratch/rails_timestamps_test
$ cd /path/to/code/rails_timestamps_test $ ruby setup_rails_project.rb 2.3.0 /path/to/code/rails *** Removing the rails app at /path/to/code/rails_timestamps_test/projects/rails-app-2-3-0 *** Checking out the rails version tagged v2.3.0 HEAD is now at beca1f2... Template#mime_type should not use Mime::Type when Action Controller is not included *** Creating the rails app at /path/to/code/rails_timestamps_test/projects/rails-app-2-3-0 *** Vendorising rails from /path/to/code/rails to /path/to/code/rails_timestamps_test/projects/rails-app-2-3-0 *** Generating rails_version_test.rb in /path/to/code/rails_timestamps_test/projects/rails-app-2-3-0/test/unit to ensure we are testing against the correct version of rails *** Copying assets to the new rails app ****** Linking /path/to/code/rails_timestamps_test/assets/person_test.rb to /path/to/code/rails_timestamps_test/projects/rails-app-2-3-0/test/unit/person_test.rb ****** Linking /path/to/code/rails_timestamps_test/assets/person.rb to /path/to/code/rails_timestamps_test/projects/rails-app-2-3-0/app/models/person.rb ****** Linking /path/to/code/rails_timestamps_test/assets/database.yml to /path/to/code/rails_timestamps_test/projects/rails-app-2-3-0/config/database.yml *** Running the rails version test to ensure that we're testing against the correct version of rails Loaded suite test/unit/rails_version_test Started . Finished in 0.000327 seconds. 1 tests, 1 assertions, 0 failures, 0 errors *** Running the timestamps test Loaded suite test/unit/person_test Started .... Finished in 0.078819 seconds. 4 tests, 8 assertions, 0 failures, 0 errors
$ cd /path/to/code/rails_timestamps_test
$ ruby setup_rails_project.rb 2.2.2 /path/to/code/rails
... some lines snipped ...
*** Running the timestamps test
Loaded suite test/unit/person_test
Started
..FF
Finished in 0.069429 seconds.
1) Failure:
test_should_be_able_to_set_updated_at(PersonTest)
[test/unit/person_test.rb:35:in `test_should_be_able_to_set_updated_at'
/path/to/code/rails_timestamps_test/projects/rails-app-2-2-2/vendor/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb:94:in `__send__'
/path/to/code/rails_timestamps_test/projects/rails-app-2-2-2/vendor/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb:94:in `run']:
FAIL: Couldn't persist the mass assigned updated_at attribute.
<Thu Jan 01 00:00:00 +0000 2009> expected but was
<Sun, 19 Apr 2009 09:23:46 UTC +00:00>.
2) Failure:
test_should_be_able_to_set_updated_on(PersonTest)
[test/unit/person_test.rb:28:in `test_should_be_able_to_set_updated_on'
/path/to/code/rails_timestamps_test/projects/rails-app-2-2-2/vendor/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb:94:in `__send__'
/path/to/code/rails_timestamps_test/projects/rails-app-2-2-2/vendor/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb:94:in `run']:
FAIL: Couldn't persist the mass assigned updated_on attribute.
<Thu, 01 Jan 2009> expected but was
<Sun Apr 19 09:23:46 UTC 2009>.
4 tests, 8 assertions, 2 failures, 0 errors
$ cd /path/to/code/rails_timestamps_test
$ ruby setup_rails_project.rb made.up.tag /path/to/code/rails
... some lines snipped ...
Loaded suite test/unit/rails_version_test
Started
F
Finished in 0.045543 seconds.
1) Failure:
test_should_be_using_rails_made_up_tag(RailsVersionTest)
[test/unit/rails_version_test.rb:6:in `test_should_be_using_rails_made_up_tag'
/path/to/code/rails_timestamps_test/projects/rails-app-made-up-tag/vendor/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb:94:in `__send__'
/path/to/code/rails_timestamps_test/projects/rails-app-made-up-tag/vendor/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb:94:in `run']:
<"made.up.tag"> expected but was
<"2.2.2">.
1 tests, 1 assertions, 1 failures, 0 errors
1 Alex MacCaw raised the issue in reference to number eight in the list of 10 cools things in Rails 2.3.
deferred until inspiration hits
by
Chris Roos
is licensed under a
Creative Commons Attribution 2.0 UK: England & Wales License