timestamped_column 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,16 +1,32 @@
1
- Time-stamped Column
2
- ===================
1
+ # timestamped_column [![Build Status](https://secure.travis-ci.org/JamesBrooks/timestamped_column.png)](http://travis-ci.org/JamesBrooks/timestamped_column>) [![Dependency Status](https://gemnasium.com/JamesBrooks/timestamped_column.png)](https://gemnasium.com/JamesBrooks/timestamped_column)
3
2
 
4
- Records modified time for individual columns.
3
+ Records the modification time for specific database columns on individual records (using ActiveRecord).
5
4
 
6
- Usage (in a model)
7
- ------------------
8
5
 
9
- `timestamped_column :email_address`
6
+ ## Compatibility
10
7
 
11
- Records the most recent modification time of `:email_address` to `:email_address_updated_at` (defaults to `name_updated_at`)
8
+ Tested and works with:
12
9
 
10
+ * Ruby: 1.8.7, 1.9.2, 1.9.3 and REE.
11
+ * Rails: 3.0, 3.1, 3.2 and edge.
13
12
 
14
- `timestamped_column :email_address, :column => :email_address_changed_at`
15
13
 
16
- Records the most recent modification time of `:email_address` to `:email_address_changed_at`
14
+ ## Installation
15
+
16
+ Add `timestamped_column` to your `Gemfile`:
17
+
18
+ ```
19
+ gem 'timestamped_column'
20
+ ```
21
+
22
+
23
+ ## Usage
24
+
25
+ Usage is similar to how `created_at`/`updated_at` function in Rails. All you need to start tracking attribute modification times is to add a new column to store the modification value. The column that tracks the modification value should be suffxed with either `_updated_at` or `_updated_on`.
26
+
27
+
28
+ ## Example
29
+
30
+ If you have a model `User` with an attribute `name` that you want to track the modification time of you just simple add an column named `name_updated_at` (or `name_updated_on`) to the `users` table.
31
+
32
+ `timestamped_column` checked for the presence of columns named like this and automatically updates these when the attributes they track are changed.
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ begin
9
+ require 'rdoc/task'
10
+ rescue LoadError
11
+ require 'rdoc/rdoc'
12
+ require 'rake/rdoctask'
13
+ RDoc::Task = Rake::RDocTask
14
+ end
15
+
16
+ require 'rspec/core/rake_task'
17
+ RSpec::Core::RakeTask.new(:spec)
18
+
19
+ RDoc::Task.new(:rdoc) do |rdoc|
20
+ rdoc.rdoc_dir = 'rdoc'
21
+ rdoc.title = 'TimestampedColumn'
22
+ rdoc.options << '--line-numbers'
23
+ rdoc.rdoc_files.include('README.rdoc')
24
+ rdoc.rdoc_files.include('lib/**/*.rb')
25
+ end
26
+
27
+ Bundler::GemHelper.install_tasks
28
+
29
+ task :default => :spec
@@ -0,0 +1,57 @@
1
+ module ActiveRecord
2
+ # = Active Record Column Timestamp
3
+ #
4
+ # Automatically timestamps when particular attributes (columns) have been changed
5
+ # if the table has fields suffixed with <tt>_updated_at/_updated_on</tt>
6
+ #
7
+ # Example: A table with a field <tt>user_name</tt> would have it's modification time
8
+ # recorded if a field named <tt>user_name_updated_at</tt> exists.
9
+ module TimestampedColumn
10
+ private
11
+ def create(*args) #:nodoc:
12
+ update_timestamp_attributes
13
+ super
14
+ end
15
+
16
+ def update(*args) #:nodoc:
17
+ update_timestamp_attributes
18
+ super
19
+ end
20
+
21
+ def update_timestamp_attributes #:nodoc:
22
+ current_time = current_time_from_proper_timezone
23
+
24
+ timestamped_attributes_in_model.each do |attribute, timestamp_attribute|
25
+ if attribute_changed?(attribute)
26
+ write_attribute(timestamp_attribute, current_time)
27
+ end
28
+ end
29
+ end
30
+
31
+ def timestamped_attributes_in_model #:nodoc:
32
+ {}.tap do |timestamped_attributes|
33
+ self.class.column_names.each do |column|
34
+ if attribute = timestamp_attribute_for_column(column)
35
+ timestamped_attributes[column] = attribute
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ def timestamp_attribute_for_column(column) #:nodoc:
42
+ self.class.column_names.detect { |c| %r{(#{possible_timestamp_attributes_for_column(column).join('|')})$} =~ c }
43
+ end
44
+
45
+ def possible_timestamp_attributes_for_column(column) #:nodoc:
46
+ column_timestamp_attribute_suffixes.map { |suffix| [ column, suffix].join }
47
+ end
48
+
49
+ def column_timestamp_attribute_suffixes #:nodoc:
50
+ ['_updated_at', '_updated_on']
51
+ end
52
+
53
+ def current_time_from_proper_timezone # from ActiveRecord::Timestamp
54
+ self.class.default_timezone == :utc ? Time.now.utc : Time.now
55
+ end
56
+ end
57
+ end
@@ -1,3 +1,3 @@
1
1
  module TimestampedColumn
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,2 +1,6 @@
1
- require 'active_support/concern'
2
- require 'timestamped_column/active_record'
1
+ require "timestamped_column/version"
2
+ require "timestamped_column/active_record/timestamped_column"
3
+
4
+ module TimestampedColumn
5
+ ActiveRecord::Base.send :include, ActiveRecord::TimestampedColumn
6
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
3
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
4
+
5
+ require File.expand_path('../config/application', __FILE__)
6
+
7
+ Dummy::Application.load_tasks
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+ # attr_accessible :title, :body
3
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require 'rails/all'
4
+
5
+ Bundler.require
6
+ require "timestamped_column"
7
+
8
+ module Dummy
9
+ class Application < Rails::Application
10
+ end
11
+ end
12
+
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ gemfile = File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ if File.exist?(gemfile)
5
+ ENV['BUNDLE_GEMFILE'] = gemfile
6
+ require 'bundler'
7
+ Bundler.setup
8
+ end
9
+
10
+ $:.unshift File.expand_path('../../../../lib', __FILE__)
@@ -0,0 +1,5 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: db/test.sqlite3
4
+ pool: 5
5
+ timeout: 5000
@@ -0,0 +1,5 @@
1
+ # Load the rails application
2
+ require File.expand_path('../application', __FILE__)
3
+
4
+ # Initialize the rails application
5
+ Dummy::Application.initialize!
@@ -0,0 +1,12 @@
1
+ Dummy::Application.configure do
2
+ config.cache_classes = true
3
+ config.serve_static_assets = true
4
+ config.static_cache_control = "public, max-age=3600"
5
+ config.whiny_nils = true
6
+ config.consider_all_requests_local = true
7
+ config.action_controller.perform_caching = false
8
+ config.action_dispatch.show_exceptions = false
9
+ config.action_controller.allow_forgery_protection = false
10
+ config.action_mailer.delivery_method = :test
11
+ config.active_support.deprecation = :stderr
12
+ end
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run Dummy::Application
@@ -0,0 +1,10 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def change
3
+ create_table :users do |t|
4
+ t.string :name, :email, :phone
5
+ t.datetime :name_updated_at, :email_updated_at
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: UTF-8
2
+ # This file is auto-generated from the current state of the database. Instead
3
+ # of editing this file, please use the migrations feature of Active Record to
4
+ # incrementally modify your database, and then regenerate this schema definition.
5
+ #
6
+ # Note that this schema.rb definition is the authoritative source for your
7
+ # database schema. If you need to create the application database on another
8
+ # system, you should be using db:schema:load, not running all the migrations
9
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
11
+ #
12
+ # It's strongly recommended to check this file into your version control system.
13
+
14
+ ActiveRecord::Schema.define(:version => 20120507214419) do
15
+
16
+ create_table "users", :force => true do |t|
17
+ t.string "name"
18
+ t.string "email"
19
+ t.string "phone"
20
+ t.datetime "name_updated_at"
21
+ t.datetime "email_updated_at"
22
+ t.datetime "created_at", :null => false
23
+ t.datetime "updated_at", :null => false
24
+ end
25
+
26
+ end
Binary file
@@ -0,0 +1,133 @@
1
+ SQL (0.2ms)  SELECT name
2
+ FROM sqlite_master
3
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
4
+ 
5
+ SQL (0.5ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES ('2012-05-08 15:57:16.011480', NULL, NULL, 'Joe User', '2012-05-08 15:57:16.009622', NULL, '2012-05-08 15:57:16.011480')
6
+ SQL (0.5ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES ('2012-05-08 15:57:16.054429', NULL, NULL, 'Joe User', '2012-05-08 15:57:16.026902', NULL, '2012-05-08 15:57:16.054429')
7
+ SQL (0.4ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES ('2012-05-08 15:57:16.060055', 'joe.user@email.com', '2012-05-08 15:57:16.058203', 'Joe User', '2012-05-08 15:57:16.058203', '123-456-7890', '2012-05-08 15:57:16.060055')
8
+ SQL (0.4ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES ('2012-05-08 15:57:16.070242', 'joe.user@email.com', '2012-05-08 15:57:16.068367', 'Joe User', '2012-05-08 15:57:16.068367', '123-456-7890', '2012-05-08 15:57:16.070242')
9
+ SQL (0.4ms) UPDATE "users" SET "phone" = '000-000-0000', "updated_at" = '2012-05-08 15:57:16.075703' WHERE ("users"."id" = 1)
10
+ SQL (0.4ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES ('2012-05-08 15:57:16.081214', 'joe.user@email.com', '2012-05-08 15:57:16.079271', 'Joe User', '2012-05-08 15:57:16.079271', '123-456-7890', '2012-05-08 15:57:16.081214')
11
+ SQL (0.4ms) UPDATE "users" SET "phone" = '000-000-0000', "updated_at" = '2012-05-08 15:57:16.084974' WHERE ("users"."id" = 1)
12
+ SQL (0.4ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES ('2012-05-08 15:57:16.090262', 'joe.user@email.com', '2012-05-08 15:57:16.088239', 'Joe User', '2012-05-08 15:57:16.088239', '123-456-7890', '2012-05-08 15:57:16.090262')
13
+ SQL (0.4ms) UPDATE "users" SET "name" = 'John Blogs', "name_updated_at" = '2012-05-08 16:57:16.092567', "updated_at" = '2012-05-08 16:57:16.094518' WHERE ("users"."id" = 1)
14
+ SQL (0.3ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES ('2012-05-08 15:57:16.100080', 'joe.user@email.com', '2012-05-08 15:57:16.098232', 'Joe User', '2012-05-08 15:57:16.098232', '123-456-7890', '2012-05-08 15:57:16.100080')
15
+ SQL (0.4ms) UPDATE "users" SET "name" = 'John Blogs', "name_updated_at" = '2012-05-08 16:57:16.102151', "updated_at" = '2012-05-08 16:57:16.104267' WHERE ("users"."id" = 1)
16
+ SQL (0.4ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES ('2012-05-08 15:57:16.111782', 'joe.user@email.com', '2012-05-08 15:57:16.109988', 'Joe User', '2012-05-08 15:57:16.109988', '123-456-7890', '2012-05-08 15:57:16.111782')
17
+ SQL (0.4ms) UPDATE "users" SET "name_updated_at" = '2012-05-07 15:57:16.113431', "updated_at" = '2012-05-08 15:57:16.118064' WHERE ("users"."id" = 1)
18
+  (0.5ms) begin transaction
19
+  (0.1ms) rollback transaction
20
+  (0.1ms) begin transaction
21
+  (0.1ms) rollback transaction
22
+  (0.1ms) begin transaction
23
+  (0.0ms) SAVEPOINT active_record_1
24
+ SQL (9.1ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["email", nil], ["email_updated_at", nil], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["phone", nil], ["updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00]]
25
+  (0.1ms) RELEASE SAVEPOINT active_record_1
26
+  (0.5ms) rollback transaction
27
+  (0.1ms) begin transaction
28
+  (0.0ms) rollback transaction
29
+  (0.0ms) begin transaction
30
+  (0.0ms) SAVEPOINT active_record_1
31
+ SQL (0.5ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["email", nil], ["email_updated_at", nil], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["phone", nil], ["updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00]]
32
+  (0.0ms) RELEASE SAVEPOINT active_record_1
33
+  (10.5ms) rollback transaction
34
+  (0.1ms) begin transaction
35
+  (0.1ms) SAVEPOINT active_record_1
36
+ SQL (0.6ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["email", "joe.user@email.com"], ["email_updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["phone", "123-456-7890"], ["updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00]]
37
+  (0.0ms) RELEASE SAVEPOINT active_record_1
38
+  (2.4ms) rollback transaction
39
+  (0.1ms) begin transaction
40
+  (0.0ms) SAVEPOINT active_record_1
41
+ SQL (0.6ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["email", "joe.user@email.com"], ["email_updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["phone", "123-456-7890"], ["updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00]]
42
+  (0.0ms) RELEASE SAVEPOINT active_record_1
43
+  (0.1ms) SAVEPOINT active_record_1
44
+  (0.5ms) UPDATE "users" SET "phone" = '000-000-0000', "updated_at" = '2012-05-08 15:59:37.252409' WHERE "users"."id" = 1
45
+  (0.0ms) RELEASE SAVEPOINT active_record_1
46
+  (0.6ms) rollback transaction
47
+  (0.1ms) begin transaction
48
+  (0.0ms) SAVEPOINT active_record_1
49
+ SQL (0.6ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["email", "joe.user@email.com"], ["email_updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["phone", "123-456-7890"], ["updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00]]
50
+  (0.0ms) RELEASE SAVEPOINT active_record_1
51
+  (0.0ms) SAVEPOINT active_record_1
52
+  (0.4ms) UPDATE "users" SET "phone" = '000-000-0000', "updated_at" = '2012-05-08 15:59:37.263297' WHERE "users"."id" = 1
53
+  (0.0ms) RELEASE SAVEPOINT active_record_1
54
+  (2.8ms) rollback transaction
55
+  (0.1ms) begin transaction
56
+  (0.1ms) SAVEPOINT active_record_1
57
+ SQL (0.6ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["email", "joe.user@email.com"], ["email_updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["phone", "123-456-7890"], ["updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00]]
58
+  (0.1ms) RELEASE SAVEPOINT active_record_1
59
+  (2.7ms) rollback transaction
60
+  (0.1ms) begin transaction
61
+  (0.0ms) SAVEPOINT active_record_1
62
+ SQL (0.6ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["email", "joe.user@email.com"], ["email_updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["phone", "123-456-7890"], ["updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00]]
63
+  (0.0ms) RELEASE SAVEPOINT active_record_1
64
+  (3.1ms) rollback transaction
65
+  (0.1ms) begin transaction
66
+  (0.0ms) SAVEPOINT active_record_1
67
+ SQL (0.6ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["email", "joe.user@email.com"], ["email_updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00], ["phone", "123-456-7890"], ["updated_at", Tue, 08 May 2012 15:59:37 UTC +00:00]]
68
+  (0.0ms) RELEASE SAVEPOINT active_record_1
69
+  (0.1ms) SAVEPOINT active_record_1
70
+  (0.4ms) UPDATE "users" SET "name_updated_at" = '2012-05-07 15:59:37.289174', "updated_at" = '2012-05-08 15:59:37.293176' WHERE "users"."id" = 1
71
+  (0.0ms) RELEASE SAVEPOINT active_record_1
72
+  (0.6ms) rollback transaction
73
+  (0.5ms) begin transaction
74
+  (0.1ms) rollback transaction
75
+  (0.1ms) begin transaction
76
+  (0.1ms) rollback transaction
77
+  (0.1ms) begin transaction
78
+  (0.0ms) SAVEPOINT active_record_1
79
+ SQL (5.0ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:53 UTC +00:00], ["email", nil], ["email_updated_at", nil], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:53 UTC +00:00], ["phone", nil], ["updated_at", Tue, 08 May 2012 15:59:53 UTC +00:00]]
80
+  (0.1ms) RELEASE SAVEPOINT active_record_1
81
+  (0.6ms) rollback transaction
82
+  (0.1ms) begin transaction
83
+  (0.1ms) rollback transaction
84
+  (0.0ms) begin transaction
85
+  (0.0ms) SAVEPOINT active_record_1
86
+ SQL (0.5ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:53 UTC +00:00], ["email", nil], ["email_updated_at", nil], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:53 UTC +00:00], ["phone", nil], ["updated_at", Tue, 08 May 2012 15:59:53 UTC +00:00]]
87
+  (0.1ms) RELEASE SAVEPOINT active_record_1
88
+  (0.6ms) rollback transaction
89
+  (0.1ms) begin transaction
90
+  (0.0ms) SAVEPOINT active_record_1
91
+ SQL (0.9ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:53 UTC +00:00], ["email", "joe.user@email.com"], ["email_updated_at", Tue, 08 May 2012 15:59:53 UTC +00:00], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:53 UTC +00:00], ["phone", "123-456-7890"], ["updated_at", Tue, 08 May 2012 15:59:53 UTC +00:00]]
92
+  (0.1ms) RELEASE SAVEPOINT active_record_1
93
+  (0.5ms) rollback transaction
94
+  (0.1ms) begin transaction
95
+  (0.0ms) SAVEPOINT active_record_1
96
+ SQL (0.6ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:53 UTC +00:00], ["email", "joe.user@email.com"], ["email_updated_at", Tue, 08 May 2012 15:59:53 UTC +00:00], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:53 UTC +00:00], ["phone", "123-456-7890"], ["updated_at", Tue, 08 May 2012 15:59:53 UTC +00:00]]
97
+  (0.1ms) RELEASE SAVEPOINT active_record_1
98
+  (0.1ms) SAVEPOINT active_record_1
99
+  (0.5ms) UPDATE "users" SET "phone" = '000-000-0000', "updated_at" = '2012-05-08 15:59:53.987355' WHERE "users"."id" = 1
100
+  (0.0ms) RELEASE SAVEPOINT active_record_1
101
+  (0.6ms) rollback transaction
102
+  (0.1ms) begin transaction
103
+  (0.1ms) SAVEPOINT active_record_1
104
+ SQL (0.6ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:53 UTC +00:00], ["email", "joe.user@email.com"], ["email_updated_at", Tue, 08 May 2012 15:59:53 UTC +00:00], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:53 UTC +00:00], ["phone", "123-456-7890"], ["updated_at", Tue, 08 May 2012 15:59:53 UTC +00:00]]
105
+  (0.0ms) RELEASE SAVEPOINT active_record_1
106
+  (0.0ms) SAVEPOINT active_record_1
107
+  (0.4ms) UPDATE "users" SET "phone" = '000-000-0000', "updated_at" = '2012-05-08 15:59:53.998711' WHERE "users"."id" = 1
108
+  (0.1ms) RELEASE SAVEPOINT active_record_1
109
+  (0.5ms) rollback transaction
110
+  (0.1ms) begin transaction
111
+  (0.0ms) SAVEPOINT active_record_1
112
+ SQL (0.5ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:54 UTC +00:00], ["email", "joe.user@email.com"], ["email_updated_at", Tue, 08 May 2012 15:59:54 UTC +00:00], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:54 UTC +00:00], ["phone", "123-456-7890"], ["updated_at", Tue, 08 May 2012 15:59:54 UTC +00:00]]
113
+  (0.0ms) RELEASE SAVEPOINT active_record_1
114
+  (0.1ms) SAVEPOINT active_record_1
115
+  (0.4ms) UPDATE "users" SET "name" = 'John Blogs', "name_updated_at" = '2012-05-08 16:59:54.006275', "updated_at" = '2012-05-08 16:59:54.008192' WHERE "users"."id" = 1
116
+  (0.0ms) RELEASE SAVEPOINT active_record_1
117
+  (0.9ms) rollback transaction
118
+  (0.1ms) begin transaction
119
+  (0.0ms) SAVEPOINT active_record_1
120
+ SQL (0.5ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:54 UTC +00:00], ["email", "joe.user@email.com"], ["email_updated_at", Tue, 08 May 2012 15:59:54 UTC +00:00], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:54 UTC +00:00], ["phone", "123-456-7890"], ["updated_at", Tue, 08 May 2012 15:59:54 UTC +00:00]]
121
+  (0.0ms) RELEASE SAVEPOINT active_record_1
122
+  (0.1ms) SAVEPOINT active_record_1
123
+  (0.4ms) UPDATE "users" SET "name" = 'John Blogs', "name_updated_at" = '2012-05-08 16:59:54.016571', "updated_at" = '2012-05-08 16:59:54.018614' WHERE "users"."id" = 1
124
+  (0.0ms) RELEASE SAVEPOINT active_record_1
125
+  (0.6ms) rollback transaction
126
+  (0.1ms) begin transaction
127
+  (0.1ms) SAVEPOINT active_record_1
128
+ SQL (0.8ms) INSERT INTO "users" ("created_at", "email", "email_updated_at", "name", "name_updated_at", "phone", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 08 May 2012 15:59:54 UTC +00:00], ["email", "joe.user@email.com"], ["email_updated_at", Tue, 08 May 2012 15:59:54 UTC +00:00], ["name", "Joe User"], ["name_updated_at", Tue, 08 May 2012 15:59:54 UTC +00:00], ["phone", "123-456-7890"], ["updated_at", Tue, 08 May 2012 15:59:54 UTC +00:00]]
129
+  (0.1ms) RELEASE SAVEPOINT active_record_1
130
+  (0.1ms) SAVEPOINT active_record_1
131
+  (0.4ms) UPDATE "users" SET "name_updated_at" = '2012-05-07 15:59:54.026696', "updated_at" = '2012-05-08 15:59:54.030661' WHERE "users"."id" = 1
132
+  (0.0ms) RELEASE SAVEPOINT active_record_1
133
+  (0.6ms) rollback transaction
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,5 @@
1
+ FactoryGirl.define do
2
+ factory :user do
3
+ name 'Joe User'
4
+ end
5
+ end
@@ -0,0 +1,110 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'User with timestamped columns' do
4
+ describe 'Sanity' do
5
+ before(:each) do
6
+ @user = FactoryGirl.build(:user)
7
+ end
8
+
9
+ it 'should initialize' do
10
+ @user.should be_a_kind_of User
11
+ end
12
+
13
+ it 'should have the specified factory defaults' do
14
+ @user.name.should match 'Joe User'
15
+ @user.email.should be_nil
16
+ @user.phone.should be_nil
17
+ end
18
+
19
+ it 'should persist' do
20
+ @user.save
21
+ @user.should be_persisted
22
+ end
23
+ end
24
+
25
+
26
+ describe 'Non-persisted models' do
27
+ before(:each) do
28
+ @user = FactoryGirl.build(:user)
29
+ end
30
+
31
+ it 'should not have timestamped columns set' do
32
+ @user.name_updated_at.should be_nil
33
+ @user.email_updated_at.should be_nil
34
+ end
35
+ end
36
+
37
+
38
+ describe 'Persisting models' do
39
+ before(:each) do
40
+ @user = FactoryGirl.build(:user)
41
+ end
42
+
43
+ it 'should set timestamped column values on create for attributes with set values' do
44
+ @user.save
45
+
46
+ @user.name_updated_at.should be_a_kind_of Time
47
+ @user.email_updated_at.should be_nil
48
+ end
49
+
50
+ it 'should set timestamped column values for multiple attributes' do
51
+ @user.email = 'joe.user@email.com'
52
+ @user.phone = '123-456-7890'
53
+ @user.save
54
+
55
+ @user.name_updated_at.should be_a_kind_of Time
56
+ @user.email_updated_at.should be_a_kind_of Time
57
+ end
58
+ end
59
+
60
+ describe 'Updating models' do
61
+ before(:each) do
62
+ @user = FactoryGirl.create(:user, {
63
+ :email => 'joe.user@email.com',
64
+ :phone => '123-456-7890'
65
+ })
66
+ end
67
+
68
+ it 'should update non-timestamped fields without updating any timestamped fields (part 1)' do
69
+ expect {
70
+ @user.phone = '000-000-0000'
71
+ @user.save
72
+ }.to_not change { @user.name_updated_at }
73
+ end
74
+
75
+ it 'should update non-timestamped fields without updating any timestamped fields (part 2)' do
76
+ expect {
77
+ @user.phone = '000-000-0000'
78
+ @user.save
79
+ }.to_not change { @user.email_updated_at }
80
+ end
81
+
82
+ it 'should update an attributes timestamped column if the attribute changes' do
83
+ in_the_future do
84
+ expect {
85
+ @user.name = 'John Blogs'
86
+ @user.save
87
+ }.to change { @user.name_updated_at }
88
+ end
89
+ end
90
+
91
+ it 'should not update another timestamp column if a different timestamped attribute changes' do
92
+ in_the_future do
93
+ expect {
94
+ @user.name = 'John Blogs'
95
+ @user.save
96
+ }.to_not change { @user.email_updated_at }
97
+ end
98
+ end
99
+
100
+ it 'should allow updating of timestamp columns without complaint' do
101
+ time = 1.day.ago
102
+
103
+ @user.name_updated_at = time
104
+ @user.name_updated_at.should equal time
105
+
106
+ @user.save
107
+ @user.name_updated_at.should equal time
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,14 @@
1
+ ENV["RAILS_ENV"] ||= 'test'
2
+
3
+ require File.expand_path("../dummy/config/environment", __FILE__)
4
+ require 'rspec/rails'
5
+ require 'rspec/autorun'
6
+ require 'factory_girl_rails'
7
+ require 'timecop'
8
+
9
+ Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
10
+
11
+ RSpec.configure do |config|
12
+ config.use_transactional_fixtures = true
13
+ config.infer_base_class_for_anonymous_controllers = false
14
+ end
@@ -0,0 +1,5 @@
1
+ def in_the_future
2
+ Timecop.travel(1.hour.from_now) do
3
+ yield
4
+ end
5
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timestamped_column
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,42 +9,94 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-23 00:00:00.000000000Z
12
+ date: 2012-05-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &70338618301700 !ruby/object:Gem::Requirement
16
+ requirement: &70095850747460 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ! '>='
19
+ - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: '0'
21
+ version: '3.2'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70338618301700
24
+ version_requirements: *70095850747460
25
25
  - !ruby/object:Gem::Dependency
26
- name: activesupport
27
- requirement: &70338618301280 !ruby/object:Gem::Requirement
26
+ name: sqlite3
27
+ requirement: &70095850746380 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
- - - ! '>='
30
+ - - ~>
31
31
  - !ruby/object:Gem::Version
32
- version: '0'
33
- type: :runtime
32
+ version: 1.3.6
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70095850746380
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec-rails
38
+ requirement: &70095850745760 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '2.10'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70095850745760
47
+ - !ruby/object:Gem::Dependency
48
+ name: factory_girl_rails
49
+ requirement: &70095850744840 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 3.2.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70095850744840
58
+ - !ruby/object:Gem::Dependency
59
+ name: timecop
60
+ requirement: &70095850744260 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 0.3.5
66
+ type: :development
34
67
  prerelease: false
35
- version_requirements: *70338618301280
36
- description: Records modified time for individual columns.
68
+ version_requirements: *70095850744260
69
+ description: Records modification time for specified database columns on a per-row
70
+ basis (ActiveRecord).
37
71
  email:
38
72
  - james@jamesbrooks.net
39
73
  executables: []
40
74
  extensions: []
41
75
  extra_rdoc_files: []
42
76
  files:
43
- - lib/timestamped_column/active_record.rb
77
+ - lib/timestamped_column/active_record/timestamped_column.rb
44
78
  - lib/timestamped_column/version.rb
45
79
  - lib/timestamped_column.rb
46
80
  - MIT-LICENSE
81
+ - Rakefile
47
82
  - README.md
83
+ - spec/dummy/app/models/user.rb
84
+ - spec/dummy/config/application.rb
85
+ - spec/dummy/config/boot.rb
86
+ - spec/dummy/config/database.yml
87
+ - spec/dummy/config/environment.rb
88
+ - spec/dummy/config/environments/test.rb
89
+ - spec/dummy/config.ru
90
+ - spec/dummy/db/migrate/20120507214419_create_users.rb
91
+ - spec/dummy/db/schema.rb
92
+ - spec/dummy/db/test.sqlite3
93
+ - spec/dummy/log/test.log
94
+ - spec/dummy/Rakefile
95
+ - spec/dummy/script/rails
96
+ - spec/factories/user.rb
97
+ - spec/models/user_spec.rb
98
+ - spec/spec_helper.rb
99
+ - spec/support/timecop.rb
48
100
  homepage: https://github.com/JamesBrooks/timestamped_column
49
101
  licenses: []
50
102
  post_install_message:
@@ -65,8 +117,25 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
117
  version: '0'
66
118
  requirements: []
67
119
  rubyforge_project:
68
- rubygems_version: 1.8.6
120
+ rubygems_version: 1.8.17
69
121
  signing_key:
70
122
  specification_version: 3
71
- summary: Records modified time for individual columns.
72
- test_files: []
123
+ summary: Records column modification times.
124
+ test_files:
125
+ - spec/dummy/app/models/user.rb
126
+ - spec/dummy/config/application.rb
127
+ - spec/dummy/config/boot.rb
128
+ - spec/dummy/config/database.yml
129
+ - spec/dummy/config/environment.rb
130
+ - spec/dummy/config/environments/test.rb
131
+ - spec/dummy/config.ru
132
+ - spec/dummy/db/migrate/20120507214419_create_users.rb
133
+ - spec/dummy/db/schema.rb
134
+ - spec/dummy/db/test.sqlite3
135
+ - spec/dummy/log/test.log
136
+ - spec/dummy/Rakefile
137
+ - spec/dummy/script/rails
138
+ - spec/factories/user.rb
139
+ - spec/models/user_spec.rb
140
+ - spec/spec_helper.rb
141
+ - spec/support/timecop.rb
@@ -1,36 +0,0 @@
1
- module TimestampedColumn
2
- module ActiveRecord
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- before_save :update_timestamped_column_times
7
- cattr_accessor :timestamped_columns
8
- end
9
-
10
- module ClassMethods
11
- def timestamped_column(column, opts={})
12
- timestamp_column = opts[:column] || "#{column}_updated_at"
13
-
14
- self.timestamped_columns ||= {}
15
- self.timestamped_columns[column] = timestamp_column
16
- end
17
- end
18
-
19
- module InstanceMethods
20
- private
21
- def update_timestamped_column_times
22
- if self.timestamped_columns && changes.any?
23
- self.timestamped_columns.each do |column, timestamp_column|
24
- if changes[column.to_s]
25
- send "#{timestamp_column}=", Time.zone.now
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
33
-
34
- class ActiveRecord::Base
35
- include TimestampedColumn::ActiveRecord
36
- end