cache_flow 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +77 -0
- data/Rakefile +39 -0
- data/VERSION +1 -0
- data/cache_flow.gemspec +56 -0
- data/init.rb +1 -0
- data/lib/cache_flow.rb +13 -0
- data/test/cache_flow_test.rb +7 -0
- data/test/schema.rb +28 -0
- data/test/test_helper.rb +13 -0
- metadata +77 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Steve Richert
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
= vestal_versions
|
2
|
+
|
3
|
+
Finally, DRY ActiveRecord versioning!
|
4
|
+
|
5
|
+
<tt>acts_as_versioned</tt>[http://github.com/technoweenie/acts_as_versioned] by technoweenie[http://github.com/technoweenie] was a great start, but it failed to keep up with ActiveRecord's introduction of dirty objects in version 2.1. Additionally, each versioned model needs its own versions table that duplicates most of the original table's columns. The versions table is then populated with records that often duplicate most of the original record's attributes. All in all, not very DRY.
|
6
|
+
|
7
|
+
<tt>simply_versioned</tt>[http://github.com/mmower/simply_versioned] by mmower[http://github.com/mmower] started to move in the right direction by removing a great deal of the duplication of acts_as_versioned. It requires only one versions table and no changes whatsoever to existing models. Its versions table stores all of the model attributes as a YAML hash in a single text column. But we could be DRYer!
|
8
|
+
|
9
|
+
<tt>vestal_versions</tt>[http://github.com/laserlemon/vestal_versions] keeps in the spirit of consolidating to one versions table, polymorphically associated with its parent models. But it goes one step further by storing a serialized hash of _only_ the models' changes. Think modern version control systems. By traversing the record of changes, the models can be reverted to any point in time.
|
10
|
+
|
11
|
+
And that's just what <tt>vestal_versions</tt> does. Not only can a model be reverted to a previous version number but also to a date or time!
|
12
|
+
|
13
|
+
== Installation
|
14
|
+
|
15
|
+
In <tt>environment.rb</tt>:
|
16
|
+
|
17
|
+
Rails::Initializer.run do |config|
|
18
|
+
config.gem 'vestal_versions'
|
19
|
+
end
|
20
|
+
|
21
|
+
At your application root, run:
|
22
|
+
|
23
|
+
$ sudo rake gems:install
|
24
|
+
|
25
|
+
Next, generate and run the first and last versioning migration you'll ever need:
|
26
|
+
|
27
|
+
$ script/generate vestal_versions_migration
|
28
|
+
$ rake db:migrate
|
29
|
+
|
30
|
+
== Example
|
31
|
+
|
32
|
+
To version an ActiveRecord model, simply add <tt>versioned</tt> to your class like so:
|
33
|
+
|
34
|
+
class User < ActiveRecord::Base
|
35
|
+
versioned
|
36
|
+
|
37
|
+
validates_presence_of :first_name, :last_name
|
38
|
+
|
39
|
+
def name
|
40
|
+
"#{first_name} #{last_name}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
It's that easy! Now watch it in action...
|
45
|
+
|
46
|
+
>> u = User.create(:first_name => 'Steve', :last_name => 'Richert')
|
47
|
+
=> #<User first_name: "Steve", last_name: "Richert">
|
48
|
+
>> u.version
|
49
|
+
=> 1
|
50
|
+
>> u.update_attribute(:first_name, 'Stephen')
|
51
|
+
=> true
|
52
|
+
>> u.name
|
53
|
+
=> "Stephen Richert"
|
54
|
+
>> u.version
|
55
|
+
=> 2
|
56
|
+
>> u.revert_to(:first)
|
57
|
+
=> 1
|
58
|
+
>> u.name
|
59
|
+
=> "Steve Richert"
|
60
|
+
>> u.version
|
61
|
+
=> 1
|
62
|
+
>> u.save
|
63
|
+
=> true
|
64
|
+
>> u.version
|
65
|
+
=> 3
|
66
|
+
>> u.update_attribute(:last_name, 'Jobs')
|
67
|
+
=> true
|
68
|
+
>> u.name
|
69
|
+
=> "Steve Jobs"
|
70
|
+
>> u.version
|
71
|
+
=> 4
|
72
|
+
>> u.revert_to!(2)
|
73
|
+
=> true
|
74
|
+
>> u.name
|
75
|
+
=> "Stephen Richert"
|
76
|
+
>> u.version
|
77
|
+
=> 5
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |g|
|
9
|
+
g.name = 'cache_flow'
|
10
|
+
g.summary = %(Easily cache XML builder fragments)
|
11
|
+
g.description = %(Easily cache XML builder fragments)
|
12
|
+
g.email = 'steve.richert@gmail.com'
|
13
|
+
g.homepage = 'http://github.com/laserlemon/cache_flow'
|
14
|
+
g.authors = %w(laserlemon)
|
15
|
+
g.add_development_dependency 'thoughtbot-shoulda'
|
16
|
+
g.rubyforge_project = 'laser-lemon'
|
17
|
+
end
|
18
|
+
Jeweler::RubyforgeTasks.new do |r|
|
19
|
+
r.doc_task = 'rdoc'
|
20
|
+
end
|
21
|
+
Jeweler::GemcutterTasks.new
|
22
|
+
rescue LoadError
|
23
|
+
puts 'Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com'
|
24
|
+
end
|
25
|
+
|
26
|
+
Rake::TestTask.new do |t|
|
27
|
+
t.libs = %w(test)
|
28
|
+
t.pattern = 'test/**/*_test.rb'
|
29
|
+
end
|
30
|
+
|
31
|
+
task :default => :test
|
32
|
+
|
33
|
+
Rake::RDocTask.new do |r|
|
34
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : nil
|
35
|
+
r.rdoc_dir = 'rdoc'
|
36
|
+
r.title = ['cache_flow', version].compact.join(' ')
|
37
|
+
r.rdoc_files.include('README*')
|
38
|
+
r.rdoc_files.include('lib/**/*.rb')
|
39
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/cache_flow.gemspec
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{cache_flow}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["laserlemon"]
|
12
|
+
s.date = %q{2009-10-06}
|
13
|
+
s.description = %q{Easily cache XML builder fragments}
|
14
|
+
s.email = %q{steve.richert@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".gitignore",
|
21
|
+
"LICENSE",
|
22
|
+
"README.rdoc",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"cache_flow.gemspec",
|
26
|
+
"init.rb",
|
27
|
+
"lib/cache_flow.rb",
|
28
|
+
"test/cache_flow_test.rb",
|
29
|
+
"test/schema.rb",
|
30
|
+
"test/test_helper.rb"
|
31
|
+
]
|
32
|
+
s.homepage = %q{http://github.com/laserlemon/cache_flow}
|
33
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
34
|
+
s.require_paths = ["lib"]
|
35
|
+
s.rubyforge_project = %q{laser-lemon}
|
36
|
+
s.rubygems_version = %q{1.3.5}
|
37
|
+
s.summary = %q{Easily cache XML builder fragments}
|
38
|
+
s.test_files = [
|
39
|
+
"test/cache_flow_test.rb",
|
40
|
+
"test/schema.rb",
|
41
|
+
"test/test_helper.rb"
|
42
|
+
]
|
43
|
+
|
44
|
+
if s.respond_to? :specification_version then
|
45
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
46
|
+
s.specification_version = 3
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
50
|
+
else
|
51
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
52
|
+
end
|
53
|
+
else
|
54
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
55
|
+
end
|
56
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'cache_flow'
|
data/lib/cache_flow.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
module LaserLemon
|
2
|
+
module CacheFlow
|
3
|
+
def cache!(name = {}, options = nil, &block)
|
4
|
+
if controller = eval('@controller', block.binding)
|
5
|
+
controller.fragment_for(@target, name, options, &block)
|
6
|
+
else
|
7
|
+
yield
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
Builder::XmlMarkup.send(:include, LaserLemon::CacheFlow)
|
data/test/schema.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
ActiveRecord::Base.establish_connection(
|
2
|
+
:adapter => defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' ? 'jdbcsqlite3' : 'sqlite3',
|
3
|
+
:database => File.join(File.dirname(__FILE__), 'test.db')
|
4
|
+
)
|
5
|
+
|
6
|
+
class CreateSchema < ActiveRecord::Migration
|
7
|
+
def self.up
|
8
|
+
create_table :users, :force => true do |t|
|
9
|
+
t.string :first_name
|
10
|
+
t.string :last_name
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
CreateSchema.suppress_messages do
|
17
|
+
CreateSchema.migrate(:up)
|
18
|
+
end
|
19
|
+
|
20
|
+
class User < ActiveRecord::Base
|
21
|
+
def name
|
22
|
+
[first_name, last_name].compact.join(' ')
|
23
|
+
end
|
24
|
+
|
25
|
+
def name=(names)
|
26
|
+
self.first_name, self.last_name = names.split(' ', 2)
|
27
|
+
end
|
28
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$: << File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
$: << File.dirname(__FILE__)
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'test/unit'
|
6
|
+
require 'activerecord'
|
7
|
+
require 'actionpack'
|
8
|
+
require 'activesupport'
|
9
|
+
require 'shoulda'
|
10
|
+
require 'cache_flow'
|
11
|
+
require 'schema'
|
12
|
+
begin; require 'redgreen'; rescue LoadError; end
|
13
|
+
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cache_flow
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- laserlemon
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-06 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: thoughtbot-shoulda
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: Easily cache XML builder fragments
|
26
|
+
email: steve.richert@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE
|
33
|
+
- README.rdoc
|
34
|
+
files:
|
35
|
+
- .gitignore
|
36
|
+
- LICENSE
|
37
|
+
- README.rdoc
|
38
|
+
- Rakefile
|
39
|
+
- VERSION
|
40
|
+
- cache_flow.gemspec
|
41
|
+
- init.rb
|
42
|
+
- lib/cache_flow.rb
|
43
|
+
- test/cache_flow_test.rb
|
44
|
+
- test/schema.rb
|
45
|
+
- test/test_helper.rb
|
46
|
+
has_rdoc: true
|
47
|
+
homepage: http://github.com/laserlemon/cache_flow
|
48
|
+
licenses: []
|
49
|
+
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options:
|
52
|
+
- --charset=UTF-8
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project: laser-lemon
|
70
|
+
rubygems_version: 1.3.5
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: Easily cache XML builder fragments
|
74
|
+
test_files:
|
75
|
+
- test/cache_flow_test.rb
|
76
|
+
- test/schema.rb
|
77
|
+
- test/test_helper.rb
|