winton-acts_as_archive 0.1.1 → 0.1.3

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.
@@ -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