lukewendling-expressive_record 0.1.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/CHANGELOG +3 -0
- data/README.rdoc +36 -0
- data/Rakefile +14 -0
- data/expressive_record.gemspec +31 -0
- data/init.rb +1 -0
- data/lib/expressive_record.rb +33 -0
- metadata +66 -0
data/CHANGELOG
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
== Expressive Record
|
2
|
+
|
3
|
+
Add meaningful names for belongs_to associations to Rails 2.1 model object dirty changes (http://dev.rubyonrails.org/changeset/9127)
|
4
|
+
|
5
|
+
== Install
|
6
|
+
|
7
|
+
sudo gem install lukewendling-expressive_record --source http://gems.github.com
|
8
|
+
|
9
|
+
== Usage
|
10
|
+
|
11
|
+
ActiveRecord 2.1 introduces dirty changes; the ability to query a model object to track attribute changes before the record is saved using #changes, #changed, etc.
|
12
|
+
|
13
|
+
However, belongs_to associations are cached simply as foreign key changes, so Ticket#changes yields something like ["status_id" => {"111", "222"}], which isn't especially helpful when rolling your own ticket history mechanism.
|
14
|
+
|
15
|
+
Expressive Records turns foreign key-based changes into meaningful terms.
|
16
|
+
|
17
|
+
class Ticket < ActiveRecord::Base
|
18
|
+
include ExpressRecord
|
19
|
+
|
20
|
+
expressify_changes
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
expressify_changes uses a before_update callback to register changes in a separate log table, by convention, that has the following schema:
|
25
|
+
|
26
|
+
class CreateTicketChanges < ActiveRecord::Migration
|
27
|
+
def self.up
|
28
|
+
create_table "ticket_changes", :force => true do |t|
|
29
|
+
t.integer "ticket_id", :null => false
|
30
|
+
t.string "attribute_type", :null => false
|
31
|
+
t.text "old_value"
|
32
|
+
t.text "new_value"
|
33
|
+
t.timestamps
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('expressive_record', '0.1.0') do |p|
|
6
|
+
p.description = "Add meaningful names for belongs_to associations to Rails 2.1 model object dirty changes"
|
7
|
+
p.url = "http://github.com/lukewendling/expressive_record"
|
8
|
+
p.author = "Luke Wendling"
|
9
|
+
p.email = "luke@lukewendling.com"
|
10
|
+
p.development_dependencies = []
|
11
|
+
end
|
12
|
+
|
13
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
14
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{expressive_record}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Luke Wendling"]
|
9
|
+
s.date = %q{2008-11-17}
|
10
|
+
s.description = %q{Add meaningful names for belongs_to associations to Rails 2.1 model object dirty changes}
|
11
|
+
s.email = %q{luke@lukewendling.com}
|
12
|
+
s.extra_rdoc_files = ["CHANGELOG", "lib/expressive_record.rb", "README.rdoc"]
|
13
|
+
s.files = ["CHANGELOG", "expressive_record.gemspec", "init.rb", "lib/expressive_record.rb", "Manifest", "Rakefile", "README.rdoc"]
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.homepage = %q{http://github.com/lukewendling/expressive_record}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Expressive_record", "--main", "README.rdoc"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{expressive_record}
|
19
|
+
s.rubygems_version = %q{1.3.1}
|
20
|
+
s.summary = %q{Add meaningful names for belongs_to associations to Rails 2.1 model object dirty changes}
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
24
|
+
s.specification_version = 2
|
25
|
+
|
26
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
27
|
+
else
|
28
|
+
end
|
29
|
+
else
|
30
|
+
end
|
31
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'expressive_record'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ExpressiveRecord
|
2
|
+
def self.included(base)
|
3
|
+
base.extend ClassMethods
|
4
|
+
end
|
5
|
+
|
6
|
+
def express_changes
|
7
|
+
ActiveRecord::Base.transaction do
|
8
|
+
self.changes.each do |attr, values|
|
9
|
+
valuefied = valuefy(attr, values)
|
10
|
+
ticket_changes.create(:attribute_type => attr, :old_value => valuefied[0], :new_value => valuefied[1])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
# find association's meaningful value (i.e. user.name instead of user id)
|
17
|
+
def valuefy(attr, values, assoc_attr = :name)
|
18
|
+
# TODO: is there a better way to determine if an attr is an association
|
19
|
+
if attr.ends_with?('_id')
|
20
|
+
assoc = self.send(attr.gsub(/_id$/,'').to_sym)
|
21
|
+
return [(values[0].nil? ? '-' : assoc.class.find(values[0]).send(assoc_attr)), assoc.class.find(values[1]).send(assoc_attr)]
|
22
|
+
else
|
23
|
+
return values
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
def expressify_changes
|
29
|
+
before_update do |record|
|
30
|
+
record.express_changes
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lukewendling-expressive_record
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Luke Wendling
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-11-17 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Add meaningful names for belongs_to associations to Rails 2.1 model object dirty changes
|
17
|
+
email: luke@lukewendling.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- CHANGELOG
|
24
|
+
- lib/expressive_record.rb
|
25
|
+
- README.rdoc
|
26
|
+
files:
|
27
|
+
- CHANGELOG
|
28
|
+
- expressive_record.gemspec
|
29
|
+
- init.rb
|
30
|
+
- lib/expressive_record.rb
|
31
|
+
- Manifest
|
32
|
+
- Rakefile
|
33
|
+
- README.rdoc
|
34
|
+
has_rdoc: true
|
35
|
+
homepage: http://github.com/lukewendling/expressive_record
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options:
|
38
|
+
- --line-numbers
|
39
|
+
- --inline-source
|
40
|
+
- --title
|
41
|
+
- Expressive_record
|
42
|
+
- --main
|
43
|
+
- README.rdoc
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "1.2"
|
57
|
+
version:
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project: expressive_record
|
61
|
+
rubygems_version: 1.2.0
|
62
|
+
signing_key:
|
63
|
+
specification_version: 2
|
64
|
+
summary: Add meaningful names for belongs_to associations to Rails 2.1 model object dirty changes
|
65
|
+
test_files: []
|
66
|
+
|