winton-acts_as_archive 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,7 +2,8 @@ ActsAsArchive
2
2
  =============
3
3
 
4
4
  Don't delete your records, move them to a different table.
5
- Like <code>acts\_as\_paranoid</code>, but doesn't change all your SQL queries.
5
+
6
+ Like <code>acts\_as\_paranoid</code>, but doesn't mess with your SQL queries.
6
7
 
7
8
  Install
8
9
  -------
@@ -23,8 +24,8 @@ sudo gem install winton-acts_as_archive
23
24
  config.gem "winton-acts_as_archive", :lib => "acts_as_archive", :source => "http://gems.github.com"
24
25
  </pre>
25
26
 
26
- Models
27
- ------
27
+ Update models
28
+ -------------
28
29
 
29
30
  Add <code>acts\_as\_archive</code> to your models:
30
31
 
@@ -34,19 +35,35 @@ class Article < ActiveRecord::Base
34
35
  end
35
36
  </pre>
36
37
 
38
+ <a name="run_acts_as_archive"></a>
39
+
40
+ Run acts\_as\_archive
41
+ ---------------------
42
+
43
+ Terminal:
44
+
45
+ <pre>
46
+ cd your_rails_app
47
+ acts_as_archive
48
+ </pre>
49
+
50
+ This command creates your archive tables (<code>archived_articles</code> as per the example).
51
+
52
+ Archive tables mirror your table's structure, but with an additional <code>deleted_at</code> column.
53
+
54
+ Run this command every time you add <code>acts\_as\_archive</code> to a new model.
55
+
37
56
  That's it!
38
57
  ----------
39
58
 
40
- Next time your Rails instance boots up, the plugin replicates your table's structure into
41
- <code>archived\_articles</code> (as per the example), with an additional <code>deleted\_at</code> column.
42
-
43
59
  Use <code>destroy</code>, <code>delete</code>, and <code>delete_all</code> like you normally would.
44
- Records are copied into the archive table before being destroyed.
60
+
61
+ Records move into the archive table instead of being destroyed.
45
62
 
46
63
  What if my schema changes?
47
64
  --------------------------
48
65
 
49
- Any new migrations on your <code>acts\_as\_archive</code> table are automatically applied to the archive table.
66
+ Any new migrations on your table are automatically applied to the archive table.
50
67
 
51
68
  Query the archive
52
69
  -----------------
@@ -69,5 +86,24 @@ Article.restore_all([ 'id = ?', 1 ])
69
86
  Auto-migrate from acts\_as\_paranoid
70
87
  ------------------------------------
71
88
 
72
- If a <code>deleted\_at</code> column is present in your table, the plugin will attempt to move deleted
73
- records to the archive table, preserving the <code>deleted\_at</code> value.
89
+ If you previously used <code>acts\_as\_paranoid</code>, running the <code>acts\_as\_archive</code>
90
+ command will automatically move your deleted records to the archive table
91
+ (see <a href="#run_acts_as_archive">_Run acts\_as\_archive_</a>).
92
+
93
+ Original <code>deleted_at</code> values are preserved.
94
+
95
+ Add indexes to the archive table
96
+ --------------------------------
97
+
98
+ To keep insertions fast, there are no indexes on your archive table by default.
99
+
100
+ If you are querying your archive a lot, you will want to add indexes:
101
+
102
+ <pre>
103
+ class Article < ActiveRecord::Base
104
+ acts_as_archive :indexes => [ :id, :created_at, :deleted_at ]
105
+ end
106
+ </pre>
107
+
108
+ Run the <code>acts\_as\_archive</code> command any time you add new indexes
109
+ (see <a href="#run_acts_as_archive">_Run acts\_as\_archive_</a>).
data/Rakefile CHANGED
@@ -1,41 +1,49 @@
1
- require 'rake'
2
1
  require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/gempackagetask'
3
4
  require 'spec/rake/spectask'
4
5
 
5
6
  GEM_NAME = 'acts_as_archive'
6
- task :default => "#{GEM_NAME}.gemspec"
7
+ PKG_FILES = FileList['**/*'] - FileList['coverage', 'coverage/**/*', 'spec/db/log/*.log']
8
+
9
+ spec = Gem::Specification.new do |s|
10
+ s.author = "Winton Welsh"
11
+ s.email = "mail@wintoni.us"
12
+ s.executables << GEM_NAME
13
+ s.extra_rdoc_files = [ "README.markdown" ]
14
+ s.files = PKG_FILES.to_a
15
+ s.homepage = "http://github.com/winton/#{GEM_NAME}"
16
+ s.name = GEM_NAME
17
+ s.platform = Gem::Platform::RUBY
18
+ s.require_path = "lib"
19
+ s.summary = "Don't delete your records, move them to a different table"
20
+ s.version = "0.1.3"
21
+ end
7
22
 
8
- file "#{GEM_NAME}.gemspec" => FileList[ '{lib,spec}/**', 'Rakefile' ] do |f|
9
- # Read spec file and split out manifest section
10
- spec = File.read(f.name)
11
- parts = spec.split(" # = MANIFEST =\n")
12
- fail 'bad spec' if parts.length != 3
13
- # Determine file list from git ls-files
14
- files = `git ls-files`.
15
- split("\n").
16
- sort.
17
- reject{ |file| file =~ /^\./ }.
18
- reject { |file| file =~ /^doc/ }.
19
- map{ |file| " #{file}" }.
20
- join("\n")
21
- # Piece file back together and write
22
- parts[1] = " s.files = %w[\n#{files}\n ]\n"
23
- spec = parts.join(" # = MANIFEST =\n")
24
- File.open(f.name, 'w') { |io| io.write(spec) }
25
- puts "Updated #{f.name}"
23
+ desc "Package gem"
24
+ Rake::GemPackageTask.new(spec) do |pkg|
25
+ pkg.gem_spec = spec
26
26
  end
27
27
 
28
- # Install the gem
28
+ desc "Install gem"
29
29
  task :install do
30
+ Rake::Task['gem'].invoke
30
31
  `sudo gem uninstall #{GEM_NAME} -x`
31
- `gem build #{GEM_NAME}.gemspec`
32
- `sudo gem install #{GEM_NAME}*.gem`
33
- `rm #{GEM_NAME}*.gem`
32
+ `sudo gem install pkg/#{GEM_NAME}*.gem`
33
+ `rm -Rf pkg`
34
+ end
35
+
36
+ desc "Generate gemspec"
37
+ task :gemspec do
38
+
39
+ File.open("#{File.dirname(__FILE__)}/#{GEM_NAME}.gemspec", 'w') do |f|
40
+ f.write(spec.to_ruby)
41
+ end
34
42
  end
35
43
 
36
- # rake spec
37
44
  desc "Run specs"
38
45
  Spec::Rake::SpecTask.new do |t|
46
+ t.rcov = true
39
47
  t.spec_opts = ["--format", "specdoc", "--colour"]
40
48
  t.spec_files = FileList["spec/**/*_spec.rb"]
41
49
  end
@@ -1,40 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+
1
3
  Gem::Specification.new do |s|
2
- s.name = 'acts_as_archive'
3
- s.version = '0.1.1'
4
- s.date = '2009-04-23'
5
-
6
- s.summary = "Don't delete your records, move them to a different table"
7
- s.description = "Don't delete your records, move them to a different table"
8
-
9
- s.author = 'Winton Welsh'
10
- s.email = 'mail@wintoni.us'
11
- s.homepage = 'http://github.com/winton/acts_as_archive'
12
-
13
- # = MANIFEST =
14
- s.files = %w[
15
- CHANGELOG.markdown
16
- MIT-LICENSE
17
- README.markdown
18
- Rakefile
19
- acts_as_archive.gemspec
20
- init.rb
21
- lib/acts_as_archive.rb
22
- lib/acts_as_archive/base.rb
23
- lib/acts_as_archive/base/destroy.rb
24
- lib/acts_as_archive/base/restore.rb
25
- lib/acts_as_archive/base/table.rb
26
- lib/acts_as_archive/migration.rb
27
- rails/init.rb
28
- spec/acts_as_archive/base/destroy_spec.rb
29
- spec/acts_as_archive/base/restore_spec.rb
30
- spec/acts_as_archive/base/table_spec.rb
31
- spec/acts_as_archive/migration_spec.rb
32
- spec/db/config/database.yml.example
33
- spec/db/log/.gitignore
34
- spec/db/migrate/001_add_to_articles.rb
35
- spec/db/models/article.rb
36
- spec/spec.opts
37
- spec/spec_helper.rb
38
- ]
39
- # = MANIFEST =
40
- end
4
+ s.name = %q{acts_as_archive}
5
+ s.version = "0.1.3"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Winton Welsh"]
9
+ s.date = %q{2009-04-25}
10
+ s.default_executable = %q{acts_as_archive}
11
+ s.email = %q{mail@wintoni.us}
12
+ s.executables = ["acts_as_archive"]
13
+ s.extra_rdoc_files = ["README.markdown"]
14
+ s.files = ["acts_as_archive.gemspec", "bin", "bin/acts_as_archive", "init.rb", "lib", "lib/acts_as_archive", "lib/acts_as_archive/base", "lib/acts_as_archive/base/destroy.rb", "lib/acts_as_archive/base/restore.rb", "lib/acts_as_archive/base/table.rb", "lib/acts_as_archive/base.rb", "lib/acts_as_archive/migration.rb", "lib/acts_as_archive.rb", "MIT-LICENSE", "rails", "rails/init.rb", "Rakefile", "README.markdown", "spec", "spec/acts_as_archive", "spec/acts_as_archive/base", "spec/acts_as_archive/base/destroy_spec.rb", "spec/acts_as_archive/base/restore_spec.rb", "spec/acts_as_archive/base/table_spec.rb", "spec/acts_as_archive/base_spec.rb", "spec/acts_as_archive/migration_spec.rb", "spec/db", "spec/db/config", "spec/db/config/database.yml", "spec/db/log", "spec/db/migrate", "spec/db/migrate/001_add_to_articles.rb", "spec/db/migrate_2", "spec/db/migrate_2/001_add_to_articles.rb", "spec/db/models", "spec/db/models/article.rb", "spec/spec.opts", "spec/spec_helper.rb"]
15
+ s.homepage = %q{http://github.com/winton/acts_as_archive}
16
+ s.require_paths = ["lib"]
17
+ s.rubygems_version = %q{1.3.1}
18
+ s.summary = %q{Don't delete your records, move them to a different table}
19
+
20
+ if s.respond_to? :specification_version then
21
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
22
+ s.specification_version = 2
23
+
24
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
25
+ else
26
+ end
27
+ else
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.push File.expand_path("#{File.dirname(__FILE__)}/../lib")
4
+ require 'acts_as_archive'
5
+
6
+ puts `script/runner "ActsAsArchive.update"`
@@ -9,16 +9,25 @@ module ActsAsArchive
9
9
  end
10
10
 
11
11
  module ActMethods
12
- def acts_as_archive
13
- include Destroy
14
- include Restore
15
- include Table
12
+ def acts_as_archive(options={})
16
13
  class_eval <<-end_eval
14
+
15
+ def self.acts_as_archive?
16
+ self.to_s == #{self.to_s.inspect}
17
+ end
18
+
19
+ def self.archive_indexes
20
+ #{Array(options[:indexes]).collect(&:to_s).inspect}
21
+ end
22
+
17
23
  class Archive < ActiveRecord::Base
18
24
  self.record_timestamps = false
19
25
  self.table_name = "archived_#{self.table_name}"
20
26
  end
21
27
  end_eval
28
+ include Destroy
29
+ include Restore
30
+ include Table
22
31
  end
23
32
  end
24
33
  end
@@ -13,9 +13,10 @@ module ActsAsArchive
13
13
 
14
14
  def copy_from_archive(conditions)
15
15
  add_conditions!(where = '', conditions)
16
+ col_names = column_names - [ 'deleted_at' ]
16
17
  connection.execute(%{
17
- INSERT INTO #{table_name} (#{column_names.join(', ')})
18
- SELECT #{column_names.join(', ')}
18
+ INSERT INTO #{table_name} (#{col_names.join(', ')})
19
+ SELECT #{col_names.join(', ')}
19
20
  FROM archived_#{table_name}
20
21
  #{where}
21
22
  })
@@ -6,15 +6,17 @@ module ActsAsArchive
6
6
  unless base.included_modules.include?(InstanceMethods)
7
7
  base.send :extend, ClassMethods
8
8
  base.send :include, InstanceMethods
9
- # Create archive table when Rails starts
10
- base.create_archive_table unless $TESTING
11
9
  end
12
10
  end
13
11
 
14
12
  module ClassMethods
15
13
 
14
+ def archive_table_exists?
15
+ connection.table_exists?("archived_#{table_name}")
16
+ end
17
+
16
18
  def create_archive_table
17
- if connection.table_exists?(table_name) && !connection.table_exists?("archived_#{table_name}")
19
+ if table_exists? && !archive_table_exists?
18
20
  connection.execute(%{
19
21
  CREATE TABLE archived_#{table_name}
20
22
  ENGINE=InnoDB
@@ -25,16 +27,33 @@ module ActsAsArchive
25
27
  unless columns.include?('deleted_at')
26
28
  connection.add_column("archived_#{table_name}", :deleted_at, :datetime)
27
29
  end
28
- connection.add_index("archived_#{table_name}", :id)
29
- connection.add_index("archived_#{table_name}", :deleted_at)
30
- migrate_from_acts_as_paranoid
30
+ end
31
+ end
32
+
33
+ def create_archive_indexes
34
+ if archive_table_exists?
35
+ indexes = "SHOW INDEX FROM archived_#{table_name}"
36
+ indexes = connection.select_all(indexes).collect do |r|
37
+ r["Column_name"]
38
+ end
39
+ (archive_indexes - indexes).each do |index|
40
+ connection.add_index("archived_#{table_name}", index)
41
+ end
42
+ (indexes - archive_indexes).each do |index|
43
+ connection.remove_index("archived_#{table_name}", index)
44
+ end
31
45
  end
32
46
  end
33
47
 
34
48
  def migrate_from_acts_as_paranoid
35
49
  if column_names.include?('deleted_at')
36
- # Base::Destroy.copy_to_archive
37
- copy_to_archive('deleted_at IS NOT NULL', true)
50
+ if table_exists? && archive_table_exists?
51
+ condition = "deleted_at IS NOT NULL"
52
+ if self.count_by_sql("SELECT COUNT(*) FROM #{table_name} WHERE #{condition}") > 0
53
+ # Base::Destroy.copy_to_archive
54
+ copy_to_archive(condition, true)
55
+ end
56
+ end
38
57
  end
39
58
  end
40
59
  end
@@ -2,3 +2,15 @@ require File.expand_path(File.dirname(__FILE__) + "/../lib/acts_as_archive")
2
2
 
3
3
  ActiveRecord::Base.send(:include, ActsAsArchive::Base)
4
4
  ActiveRecord::Migration.send(:include, ActsAsArchive::Migration)
5
+
6
+ module ActsAsArchive
7
+ def self.update
8
+ Object.subclasses_of(ActiveRecord::Base).each do |klass|
9
+ if klass.respond_to?(:acts_as_archive?) && klass.acts_as_archive?
10
+ klass.create_archive_table
11
+ klass.migrate_from_acts_as_paranoid
12
+ klass.create_archive_indexes
13
+ end
14
+ end
15
+ end
16
+ end
@@ -5,17 +5,12 @@ describe ActsAsArchive::Base::Destroy do
5
5
  before(:all) do
6
6
  establish_test_db
7
7
  Article.create_archive_table
8
- @connection = ActiveRecord::Base.connection
9
8
  end
10
9
 
11
10
  describe 'delete_all!' do
12
11
 
13
- before(:each) do
14
- @articles = []
15
- @connection.execute("TRUNCATE TABLE #{Article.table_name}")
16
- 5.times do |x|
17
- @articles << Article.create(:title => "Title #{x}", :body => "Body #{x}")
18
- end
12
+ before(:all) do
13
+ create_records
19
14
  end
20
15
 
21
16
  it "should really delete all records" do
@@ -28,16 +23,13 @@ describe ActsAsArchive::Base::Destroy do
28
23
 
29
24
  describe 'delete_all' do
30
25
 
31
- before(:each) do
32
- @articles = []
33
- 5.times do |x|
34
- @articles << Article.create(:title => "Title #{x}", :body => "Body #{x}")
35
- end
26
+ before(:all) do
27
+ @articles = create_records
36
28
  end
37
29
 
38
30
  describe 'with conditions' do
39
31
 
40
- before(:each) do
32
+ before(:all) do
41
33
  # Mini delete_all parameter test
42
34
  Article.delete_all [ 'id = ?', @articles[0].id ]
43
35
  Article.delete_all "id = #{@articles[1].id}"
@@ -59,7 +51,7 @@ describe ActsAsArchive::Base::Destroy do
59
51
 
60
52
  describe 'without conditions' do
61
53
 
62
- before(:each) do
54
+ before(:all) do
63
55
  Article.delete_all
64
56
  end
65
57
 
@@ -82,11 +74,8 @@ describe ActsAsArchive::Base::Destroy do
82
74
 
83
75
  describe d do
84
76
 
85
- before(:each) do
86
- @articles = []
87
- 5.times do |x|
88
- @articles << Article.create(:title => "Title #{x}", :body => "Body #{x}")
89
- end
77
+ before(:all) do
78
+ @articles = create_records
90
79
  Article.find(@articles[0..1].collect(&:id)).each do |a|
91
80
  a.send(d)
92
81
  end
@@ -5,25 +5,17 @@ describe ActsAsArchive::Base::Restore do
5
5
  before(:all) do
6
6
  establish_test_db
7
7
  Article.create_archive_table
8
- @connection = ActiveRecord::Base.connection
9
8
  end
10
9
 
11
10
  describe 'restore_all' do
12
11
 
13
- before(:each) do
14
- @articles = []
15
- @connection.execute("TRUNCATE TABLE #{Article.table_name}")
16
- 5.times do |x|
17
- @connection.execute(%{
18
- INSERT INTO archived_#{Article.table_name} (`id`, `title`, `body`) VALUES (#{x+1}, 'Title #{x}', 'Body #{x}')
19
- })
20
- @articles << Article::Archive.find(x+1)
21
- end
12
+ before(:all) do
13
+ @articles = create_records(Article::Archive)
22
14
  end
23
15
 
24
16
  describe 'with conditions' do
25
17
 
26
- before(:each) do
18
+ before(:all) do
27
19
  # Mini restore parameter test
28
20
  Article.restore_all [ 'id = ?', @articles[0].id ]
29
21
  Article.restore_all "id = #{@articles[1].id}"
@@ -45,7 +37,7 @@ describe ActsAsArchive::Base::Restore do
45
37
 
46
38
  describe 'without conditions' do
47
39
 
48
- before(:each) do
40
+ before(:all) do
49
41
  Article.restore_all
50
42
  end
51
43
 
@@ -4,19 +4,18 @@ describe ActsAsArchive::Base::Table do
4
4
 
5
5
  before(:all) do
6
6
  establish_test_db
7
- @connection = ActiveRecord::Base.connection
7
+ Article.create_archive_table
8
8
  end
9
9
 
10
10
  describe 'create_archive_table' do
11
11
 
12
12
  before(:all) do
13
- Article.create_archive_table
14
- @article_columns = @connection.columns("articles").collect(&:name)
15
- @archive_columns = @connection.columns("archived_articles").collect(&:name)
13
+ @article_columns = connection.columns("articles").collect(&:name)
14
+ @archive_columns = connection.columns("archived_articles").collect(&:name)
16
15
  end
17
16
 
18
17
  it "should create an archive table" do
19
- @connection.table_exists?("archived_articles").should == true
18
+ connection.table_exists?("archived_articles").should == true
20
19
  end
21
20
 
22
21
  it "should create an archive table with the same structure as the original table" do
@@ -29,4 +28,47 @@ describe ActsAsArchive::Base::Table do
29
28
  (@archive_columns - @article_columns).should == [ 'deleted_at' ]
30
29
  end
31
30
  end
31
+
32
+ describe 'create_archive_indexes' do
33
+
34
+ before(:all) do
35
+ Article.create_archive_indexes
36
+ end
37
+
38
+ it "should create archive indexes" do
39
+ indexes.should == [ "id", "deleted_at" ]
40
+ end
41
+
42
+ it "should destroy archive indexes" do
43
+ Article.class_eval { acts_as_archive }
44
+ Article.create_archive_indexes
45
+ indexes.should == []
46
+ end
47
+ end
48
+
49
+ describe 'migrate_from_acts_as_paranoid' do
50
+
51
+ before(:all) do
52
+ connection.add_column(:articles, :deleted_at, :datetime)
53
+ Article.reset_column_information
54
+ end
55
+
56
+ before(:each) do
57
+ connection.execute("DELETE FROM #{Article::Archive.table_name}")
58
+ end
59
+
60
+ it "should move deleted records to the archive" do
61
+ create_records(Article, :deleted_at => Time.now)
62
+ Article.migrate_from_acts_as_paranoid
63
+ Article.count.should == 0
64
+ Article::Archive.count.should == 5
65
+ end
66
+
67
+ it "should not move non-deleted records to the archive" do
68
+ create_records
69
+ Article.migrate_from_acts_as_paranoid
70
+ Article.count.should == 5
71
+ Article::Archive.count.should == 0
72
+ end
73
+ end
32
74
  end
@@ -0,0 +1,24 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe ActsAsArchive::Base do
4
+
5
+ before(:all) do
6
+ establish_test_db
7
+ end
8
+
9
+ describe 'acts_as_archive' do
10
+
11
+ it "should add self.acts_as_archive? to the model" do
12
+ Article.respond_to?(:acts_as_archive?).should == true
13
+ end
14
+
15
+ it "should add self.archive_indexes to the model" do
16
+ Article.respond_to?(:archive_indexes).should == true
17
+ Article.archive_indexes.should == [ 'id', 'deleted_at' ]
18
+ end
19
+
20
+ it "should add Archive class to the model" do
21
+ defined?(Article::Archive).should == "constant"
22
+ end
23
+ end
24
+ end
@@ -5,32 +5,33 @@ describe ActsAsArchive::Migration do
5
5
  before(:each) do
6
6
  establish_test_db
7
7
  Article.create_archive_table
8
- @connection = ActiveRecord::Base.connection
9
8
  end
10
9
 
11
10
  describe 'method_missing_with_archive' do
12
11
 
13
- before(:each) do
14
- @old_article_columns = @connection.columns("articles").collect(&:name)
15
- @old_archive_columns = @connection.columns("archived_articles").collect(&:name)
16
- ActiveRecord::Migrator.migrate("#{SPEC}/db/migrate")
17
- @new_article_columns = @connection.columns("articles").collect(&:name)
18
- @new_archive_columns = @connection.columns("archived_articles").collect(&:name)
19
- end
20
-
21
12
  it 'should migrate both tables up' do
13
+ migrate_up
22
14
  (@new_article_columns - @old_article_columns).should == [ 'permalink' ]
23
15
  (@new_archive_columns - @old_archive_columns).should == [ 'permalink' ]
24
16
  end
25
17
 
26
18
  it 'should migrate both tables down' do
19
+ migrate_up
27
20
  @old_article_columns = @new_article_columns
28
21
  @old_archive_columns = @new_archive_columns
29
22
  ActiveRecord::Migrator.migrate("#{SPEC}/db/migrate", 0)
30
- @new_article_columns = @connection.columns("articles").collect(&:name)
31
- @new_archive_columns = @connection.columns("archived_articles").collect(&:name)
23
+ @new_article_columns = columns("articles")
24
+ @new_archive_columns = columns("archived_articles")
32
25
  (@old_article_columns - @new_article_columns).should == [ 'permalink' ]
33
26
  (@old_archive_columns - @new_archive_columns).should == [ 'permalink' ]
34
27
  end
28
+
29
+ it "should not touch the archive's deleted_at column" do
30
+ connection.add_column(:articles, :deleted_at, :datetime)
31
+ Article.reset_column_information
32
+ migrate_up("migrate_2")
33
+ (@old_article_columns - @new_article_columns).should == [ 'deleted_at' ]
34
+ (@old_archive_columns - @new_archive_columns).should == []
35
+ end
35
36
  end
36
37
  end
@@ -0,0 +1,9 @@
1
+ class AddToArticles < ActiveRecord::Migration
2
+ def self.up
3
+ remove_column :articles, :deleted_at
4
+ end
5
+
6
+ def self.down
7
+ add_column :articles, :deleted_at, :string
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  class Article < ActiveRecord::Base
2
- acts_as_archive
2
+ acts_as_archive :indexes => [ :id, :deleted_at ]
3
3
  end
@@ -1,5 +1,5 @@
1
1
  $TESTING=true
2
- SPEC = File.dirname(__FILE__)
2
+ SPEC = File.expand_path(File.dirname(__FILE__))
3
3
 
4
4
  require 'rubygems'
5
5
  require 'active_record'
@@ -16,13 +16,44 @@ def article_match?(original, copy)
16
16
  copy.id.should == original.id
17
17
  copy.title.should == original.title
18
18
  copy.body.should == original.body
19
- copy.created_at.to_s.should == original.created_at.to_s
20
- copy.updated_at.to_s.should == original.updated_at.to_s
21
19
  if copy.respond_to?(:deleted_at)
22
20
  copy.deleted_at.strftime('%j%H%M').should == Time.now.strftime('%j%H%M')
23
21
  end
24
22
  end
25
23
 
24
+ def columns(table)
25
+ connection.columns(table).collect(&:name)
26
+ end
27
+
28
+ def connection
29
+ ActiveRecord::Base.connection
30
+ end
31
+
32
+ def create_records(klass=Article, values={})
33
+ articles = []
34
+ table = klass.table_name
35
+ cols = columns(table)
36
+ connection.execute("DELETE FROM #{table}")
37
+ (1..5).collect do |x|
38
+ vals = cols.collect do |c|
39
+ if values.keys.include?(c.intern)
40
+ values[c.intern] ? "'#{values[c.intern]}'" : "NULL"
41
+ else
42
+ case c.intern
43
+ when :id; x
44
+ when :deleted_at; 'NULL'
45
+ else "'#{c.capitalize} #{x}'"
46
+ end
47
+ end
48
+ end
49
+ connection.execute(%{
50
+ INSERT INTO #{table} (#{cols.collect { |c| "`#{c}`" }.join(', ')})
51
+ VALUES (#{vals.join(', ')})
52
+ })
53
+ klass.find(x)
54
+ end
55
+ end
56
+
26
57
  def debug(object)
27
58
  puts "<pre>"
28
59
  pp object
@@ -39,18 +70,31 @@ def establish_test_db
39
70
  # Establish logger
40
71
  logger_file = File.open("#{SPEC}/db/log/test.log", 'a')
41
72
  logger_file.sync = true
42
- @logger = Logger.new logger_file
73
+ @logger = Logger.new(logger_file)
43
74
  ActiveRecord::Base.logger = @logger
44
- # Drop articles and archived_articles
45
- ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS articles")
46
- ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS archived_articles")
47
- ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS schema_migrations")
48
- # Create articles table
49
- ActiveRecord::Base.connection.create_table(:articles) do |t|
75
+ # The database should have only a simple articles table
76
+ connection.execute("DROP TABLE IF EXISTS articles")
77
+ connection.execute("DROP TABLE IF EXISTS archived_articles")
78
+ connection.execute("DROP TABLE IF EXISTS schema_migrations")
79
+ connection.create_table(:articles) do |t|
50
80
  t.string :title
51
81
  t.string :body
52
- t.timestamps
53
82
  end
54
- # Load model
55
- require "#{SPEC}/db/models/article"
83
+ # Load the model
84
+ load "#{SPEC}/db/models/article.rb"
85
+ end
86
+
87
+ def indexes
88
+ query = "SHOW INDEX FROM archived_#{Article.table_name}"
89
+ connection.select_all(query).collect do |r|
90
+ r["Column_name"]
91
+ end
92
+ end
93
+
94
+ def migrate_up(directory='migrate')
95
+ @old_article_columns = columns("articles")
96
+ @old_archive_columns = columns("archived_articles")
97
+ ActiveRecord::Migrator.migrate("#{SPEC}/db/#{directory}")
98
+ @new_article_columns = columns("articles")
99
+ @new_archive_columns = columns("archived_articles")
56
100
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: winton-acts_as_archive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Winton Welsh
@@ -9,39 +9,54 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-23 00:00:00 -07:00
13
- default_executable:
12
+ date: 2009-04-25 00:00:00 -07:00
13
+ default_executable: acts_as_archive
14
14
  dependencies: []
15
15
 
16
- description: Don't delete your records, move them to a different table
16
+ description:
17
17
  email: mail@wintoni.us
18
- executables: []
19
-
18
+ executables:
19
+ - acts_as_archive
20
20
  extensions: []
21
21
 
22
- extra_rdoc_files: []
23
-
24
- files:
25
- - CHANGELOG.markdown
26
- - MIT-LICENSE
22
+ extra_rdoc_files:
27
23
  - README.markdown
28
- - Rakefile
24
+ files:
29
25
  - acts_as_archive.gemspec
26
+ - bin
27
+ - bin/acts_as_archive
30
28
  - init.rb
31
- - lib/acts_as_archive.rb
32
- - lib/acts_as_archive/base.rb
29
+ - lib
30
+ - lib/acts_as_archive
31
+ - lib/acts_as_archive/base
33
32
  - lib/acts_as_archive/base/destroy.rb
34
33
  - lib/acts_as_archive/base/restore.rb
35
34
  - lib/acts_as_archive/base/table.rb
35
+ - lib/acts_as_archive/base.rb
36
36
  - lib/acts_as_archive/migration.rb
37
+ - lib/acts_as_archive.rb
38
+ - MIT-LICENSE
39
+ - rails
37
40
  - rails/init.rb
41
+ - Rakefile
42
+ - README.markdown
43
+ - spec
44
+ - spec/acts_as_archive
45
+ - spec/acts_as_archive/base
38
46
  - spec/acts_as_archive/base/destroy_spec.rb
39
47
  - spec/acts_as_archive/base/restore_spec.rb
40
48
  - spec/acts_as_archive/base/table_spec.rb
49
+ - spec/acts_as_archive/base_spec.rb
41
50
  - spec/acts_as_archive/migration_spec.rb
42
- - spec/db/config/database.yml.example
43
- - spec/db/log/.gitignore
51
+ - spec/db
52
+ - spec/db/config
53
+ - spec/db/config/database.yml
54
+ - spec/db/log
55
+ - spec/db/migrate
44
56
  - spec/db/migrate/001_add_to_articles.rb
57
+ - spec/db/migrate_2
58
+ - spec/db/migrate_2/001_add_to_articles.rb
59
+ - spec/db/models
45
60
  - spec/db/models/article.rb
46
61
  - spec/spec.opts
47
62
  - spec/spec_helper.rb
@@ -1,4 +0,0 @@
1
- Version 0.1.0
2
- -------------
3
-
4
- *
File without changes