archive_2s 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ coverage
5
+ .idea
6
+ .rbx
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create ruby-1.8.7@archive_2s
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :gemcutter
2
+
3
+ # Specify your gem's dependencies in archive_2s.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,118 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ archive_2s (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ actionmailer (3.1.1)
10
+ actionpack (= 3.1.1)
11
+ mail (~> 2.3.0)
12
+ actionpack (3.1.1)
13
+ activemodel (= 3.1.1)
14
+ activesupport (= 3.1.1)
15
+ builder (~> 3.0.0)
16
+ erubis (~> 2.7.0)
17
+ i18n (~> 0.6)
18
+ rack (~> 1.3.2)
19
+ rack-cache (~> 1.1)
20
+ rack-mount (~> 0.8.2)
21
+ rack-test (~> 0.6.1)
22
+ sprockets (~> 2.0.2)
23
+ activemodel (3.1.1)
24
+ activesupport (= 3.1.1)
25
+ builder (~> 3.0.0)
26
+ i18n (~> 0.6)
27
+ activerecord (3.1.1)
28
+ activemodel (= 3.1.1)
29
+ activesupport (= 3.1.1)
30
+ arel (~> 2.2.1)
31
+ tzinfo (~> 0.3.29)
32
+ activeresource (3.1.1)
33
+ activemodel (= 3.1.1)
34
+ activesupport (= 3.1.1)
35
+ activesupport (3.1.1)
36
+ multi_json (~> 1.0)
37
+ arel (2.2.1)
38
+ builder (3.0.0)
39
+ columnize (0.3.4)
40
+ diff-lcs (1.1.3)
41
+ erubis (2.7.0)
42
+ hike (1.2.1)
43
+ i18n (0.6.0)
44
+ json (1.6.1)
45
+ linecache (0.46)
46
+ rbx-require-relative (> 0.0.4)
47
+ mail (2.3.0)
48
+ i18n (>= 0.4.0)
49
+ mime-types (~> 1.16)
50
+ treetop (~> 1.4.8)
51
+ mime-types (1.17.2)
52
+ multi_json (1.0.3)
53
+ polyglot (0.3.3)
54
+ rack (1.3.5)
55
+ rack-cache (1.1)
56
+ rack (>= 0.4)
57
+ rack-mount (0.8.3)
58
+ rack (>= 1.0.0)
59
+ rack-ssl (1.3.2)
60
+ rack
61
+ rack-test (0.6.1)
62
+ rack (>= 1.0)
63
+ rails (3.1.1)
64
+ actionmailer (= 3.1.1)
65
+ actionpack (= 3.1.1)
66
+ activerecord (= 3.1.1)
67
+ activeresource (= 3.1.1)
68
+ activesupport (= 3.1.1)
69
+ bundler (~> 1.0)
70
+ railties (= 3.1.1)
71
+ railties (3.1.1)
72
+ actionpack (= 3.1.1)
73
+ activesupport (= 3.1.1)
74
+ rack-ssl (~> 1.3.2)
75
+ rake (>= 0.8.7)
76
+ rdoc (~> 3.4)
77
+ thor (~> 0.14.6)
78
+ rake (0.9.2.2)
79
+ rbx-require-relative (0.0.5)
80
+ rcov (0.9.11)
81
+ rdoc (3.11)
82
+ json (~> 1.4)
83
+ rspec (2.7.0)
84
+ rspec-core (~> 2.7.0)
85
+ rspec-expectations (~> 2.7.0)
86
+ rspec-mocks (~> 2.7.0)
87
+ rspec-core (2.7.1)
88
+ rspec-expectations (2.7.0)
89
+ diff-lcs (~> 1.1.2)
90
+ rspec-mocks (2.7.0)
91
+ ruby-debug (0.10.4)
92
+ columnize (>= 0.1)
93
+ ruby-debug-base (~> 0.10.4.0)
94
+ ruby-debug-base (0.10.4)
95
+ linecache (>= 0.3)
96
+ sprockets (2.0.3)
97
+ hike (~> 1.2)
98
+ rack (~> 1.0)
99
+ tilt (~> 1.1, != 1.3.0)
100
+ sqlite3 (1.3.4)
101
+ thor (0.14.6)
102
+ tilt (1.3.3)
103
+ treetop (1.4.10)
104
+ polyglot
105
+ polyglot (>= 0.3.1)
106
+ tzinfo (0.3.31)
107
+
108
+ PLATFORMS
109
+ ruby
110
+
111
+ DEPENDENCIES
112
+ archive_2s!
113
+ bundler (>= 1.0.0)
114
+ rails
115
+ rcov
116
+ rspec
117
+ ruby-debug
118
+ sqlite3
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 SmashTank Apps, LLC
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,30 @@
1
+ = Archive 2s
2
+
3
+ This gem provides the ability to archive a meaningful bit of information. This is good for use with friendly_id or stats.
4
+ It will save to a single table that is created via a migration copied from the rake task
5
+
6
+ == Usage
7
+ archive_2s accepts two optional parameters, :method_name and :include_by_default
8
+ class Item < ActiveRecord::Base
9
+ archive_2s :method_name => :name, :include_by_default => true
10
+
11
+ def name
12
+ [self.first_name, self.middle_initial, self.last_name].join(' ')
13
+ end
14
+ end
15
+ :method_name is the methods return value you wish to save and :include_by_default will include archived results when you
16
+ fetch by id only (as all that is saved is the id and a value of a method)
17
+
18
+ All objects returned are readonly.
19
+
20
+ ==Todo
21
+ * make some proxy magic so if one calls a relationship if can search the archive too
22
+ * use wants rather then returning based on length
23
+ * drop the id column and use the index for the model
24
+ * make the doco usefull
25
+
26
+ == Copyright
27
+
28
+ Copyright (c) 2011 SmashTank Apps, LLC. See LICENSE.txt for
29
+ further details.
30
+
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+ require 'rake'
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc "Run all specs."
7
+ RSpec::Core::RakeTask.new(:spec) do |t|
8
+ t.pattern = 'spec/**/*_spec.rb'
9
+ t.verbose = false
10
+ end
11
+
12
+ RSpec::Core::RakeTask.new(:rcov) do |t|
13
+ t.rcov = true
14
+ t.rcov_opts = %q[--exclude "spec,gems" --include-file "lib/archive_2s"]
15
+ t.verbose = true
16
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/archive_2s/version", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "archive_2s"
6
+ s.version = Archive2s::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ['SmashTank Apps, LLC','Eric Harrison']
9
+ s.email = ['dev@smashtankapps.com']
10
+ s.homepage = "http://rubygems.org/gems/archive_2s"
11
+ s.summary = "A little gem that will archive the to_s of ActiveRecord Models"
12
+ s.description = "Sometimes you just need a descriptive value of an item you are archiving. This is what archive_2s was made for."
13
+
14
+ s.required_rubygems_version = ">= 1.3.6"
15
+ s.rubyforge_project = "archive_2s"
16
+
17
+ s.add_development_dependency "bundler", ">= 1.0.0"
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
21
+ s.require_path = 'lib'
22
+
23
+ s.add_development_dependency "ruby-debug"
24
+ s.add_development_dependency "rspec"
25
+ s.add_development_dependency "rails"
26
+ s.add_development_dependency "sqlite3"
27
+ s.add_development_dependency "rcov"
28
+ end
data/bin/autospec ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'autospec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rspec-core', 'autospec')
data/bin/erubis ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'erubis' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('erubis', 'erubis')
data/bin/htmldiff ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'htmldiff' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('diff-lcs', 'htmldiff')
data/bin/ldiff ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'ldiff' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('diff-lcs', 'ldiff')
data/bin/rackup ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rackup' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rack', 'rackup')
data/bin/rails ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rails' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rails', 'rails')
data/bin/rake ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rake' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rake', 'rake')
data/bin/rake2thor ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rake2thor' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('thor', 'rake2thor')
data/bin/rcov ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rcov' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rcov', 'rcov')
data/bin/rdebug ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rdebug' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('ruby-debug', 'rdebug')
data/bin/rdoc ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rdoc' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rdoc', 'rdoc')
data/bin/ri ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'ri' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rdoc', 'ri')
data/bin/rspec ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rspec-core', 'rspec')
data/bin/thor ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'thor' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('thor', 'thor')
data/bin/tilt ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'tilt' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('tilt', 'tilt')
data/bin/tt ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'tt' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('treetop', 'tt')
@@ -0,0 +1,5 @@
1
+ class Archive2sModelGenerator < Rails::Generator::Base
2
+ def manifest
3
+ m.migration_template 'templates/create_archive_2s_model.rb', "db/migrate"
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ class CreateArchive2sModel < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :archived_to_s do |t|
4
+ t.datetime :archived_at
5
+ t.string :model_type
6
+ t.integer :model_id
7
+ t.string :archived_value
8
+ end
9
+ add_index :archived_to_s, [:model_type,:model_id,:archived_at], :name => 'model_and_archive_date_idx', :unique => true
10
+ end
11
+
12
+ def self.down
13
+ drop_table :archived_to_s
14
+ end
15
+ end
16
+
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), 'lib', 'archive_2s')
@@ -0,0 +1,28 @@
1
+ module Archive2s
2
+ class Model < ActiveRecord::Base
3
+ #TODO: drop the id column and use the index
4
+ set_table_name :archived_to_s
5
+ belongs_to :model, :polymorphic => true
6
+
7
+ def model
8
+ archived_model = model_class.new()
9
+ archived_model.id = self.model_id
10
+ #can't use self in the instance_eval/define method so make a local variable first
11
+ return_value = self.archived_value
12
+
13
+ archived_model.instance_eval do
14
+ singleton = class << self; self; end
15
+ singleton.send(:define_method, self.class.archive_2s_args[:method_name]) do
16
+ return_value
17
+ end
18
+ end
19
+
20
+ archived_model.readonly!
21
+ archived_model
22
+ end
23
+
24
+ def model_class
25
+ @model_class ||= eval(self.model_type.classify)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module Archive2s
2
+ VERSION = "0.0.1"
3
+ end
data/lib/archive_2s.rb ADDED
@@ -0,0 +1,94 @@
1
+ require "archive_2s/model"
2
+ module Archive2s
3
+ DEFAULT_ARGUMENTS = {
4
+ :method_name => :to_s,
5
+ :include_by_default => false
6
+ }
7
+ module ClassMethods
8
+ def archive_2s(args)
9
+ # don't allow multiple calls
10
+ return if self.included_modules.include?(Archive2s::InstanceMethods)
11
+
12
+ include InstanceMethods
13
+ extend ClassMethods
14
+
15
+ singleton = class << self; self; end
16
+ singleton.module_eval do
17
+ define_method(:archive_2s_args) do
18
+ @archive_2s_args
19
+ end
20
+ define_method(:archive_2s_args=) do |value|
21
+ @archive_2s_args = value
22
+ end
23
+ end
24
+ self.archive_2s_args = Archive2s::DEFAULT_ARGUMENTS.merge(args)
25
+
26
+ #TODO: make some proxy magic so if one calls a relationship if can search the archive too
27
+ if self.archive_2s_args[:include_by_default]
28
+ singleton.module_eval do
29
+ def find(*args)
30
+ begin
31
+ #might as well try AR first
32
+ super.find(*args)
33
+ rescue Exception => e
34
+ #can only fetch archived by ids so don't attempt if there were extra args
35
+ if args.flatten! && args.length != args.select{|i| i == i.to_i}.length
36
+ raise e
37
+ else
38
+ items = self.all(:conditions => ["id IN (#{(['?'] * args.length).join(',')})", *args])
39
+ items += [self.find_archived(*args - items.collect(&:id))].flatten
40
+ if args.length == items.length
41
+ items
42
+ else
43
+ raise e
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ module InstanceMethods
54
+ def self.included(base)
55
+ base.class_eval do
56
+ alias_method_chain :destroy, :archive
57
+ end
58
+ end
59
+
60
+ # wrap it all up in a transaction
61
+ def destroy_with_archive
62
+ self.class.transaction do
63
+ archived = ::Archive2s::Model.new(:model => self, :archived_value => self.send(self.class.archive_2s_args[:method_name]), :archived_at => Time.now)
64
+ archived.save!
65
+ destroy_without_archive
66
+ end
67
+ end
68
+ end
69
+
70
+ module ClassMethods
71
+ def find_archived(*ids)
72
+ ids.flatten!
73
+ #don't use scopes so it is rails 2 and 3 compliant
74
+ archived_models = ::Archive2s::Model.all(:conditions => ["model_type = ? AND model_id IN (#{(['?'] * ids.length).join(',')})", self.to_s, *ids]).collect(&:model)
75
+
76
+ if archived_models.length != ids.length
77
+ if ids.length == 1
78
+ raise ActiveRecord::RecordNotFound, "Couldn't find Archived #{self.to_s} with ID=#{ids.first}"
79
+ else
80
+ raise ActiveRecord::RecordNotFound, "Couldn't find all Archived #{self.to_s.pluralize} with IDs (#{ids.join(',')})"
81
+ end
82
+ end
83
+
84
+ #TODO: use wants
85
+ if archived_models.length > 1
86
+ archived_models
87
+ else
88
+ archived_models.first
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ ActiveRecord::Base.send :extend, Archive2s::ClassMethods
@@ -0,0 +1,99 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ class Item < ActiveRecord::Base
4
+ archive_2s :method_name => :archive_value
5
+
6
+ def to_s
7
+ "to_s"
8
+ end
9
+
10
+ def archive_value
11
+ name
12
+ end
13
+ end
14
+
15
+ class Thing < ActiveRecord::Base
16
+ archive_2s :include_by_default => true
17
+
18
+ def to_s
19
+ name
20
+ end
21
+ end
22
+
23
+ describe Archive2s do
24
+ it "should archive when item is destroyed" do
25
+ thing_one = Thing.create(:name => 'Thing One', :description => 'foo')
26
+ id = thing_one.id
27
+ thing_one.destroy
28
+ archive = ::Archive2s::Model.last
29
+ archive.model_type.should == 'Thing'
30
+ archive.model_id.should == id
31
+ end
32
+
33
+ it "find_archived should fetch only archived items" do
34
+ item_one = Item.create(:name => 'Item One', :description => 'foo')
35
+ item_two = Item.create(:name => 'Item Two', :description => 'bar')
36
+ ids = [item_one.id, item_two.id]
37
+ item_two.destroy
38
+ Item.find_archived(ids.last).should be_an_instance_of(Item)
39
+ end
40
+
41
+ it "find_archived should raise an error if it can't find an id" do
42
+ lambda {Item.find_archived(999)}.should raise_error(ActiveRecord::RecordNotFound)
43
+ end
44
+
45
+ it "find_archived should raise an error if it can't find even one of the ids" do
46
+ item_one = Item.create(:name => 'Item One', :description => 'foo')
47
+ item_two = Item.create(:name => 'Item Two', :description => 'bar')
48
+ ids = [item_one.id, item_two.id]
49
+ item_two.destroy
50
+ lambda {Item.find_archived(ids)}.should raise_error(ActiveRecord::RecordNotFound)
51
+ end
52
+
53
+ describe "include by default" do
54
+ it "should return archived results when true" do
55
+ thing_one = Thing.create(:name => 'Thing One', :description => 'foo')
56
+ thing_two = Thing.create(:name => 'Thing Two', :description => 'bar')
57
+ ids = [thing_one.id, thing_two.id]
58
+ thing_two.destroy
59
+ things = Thing.find(ids)
60
+
61
+ things.length.should == 2
62
+ things.collect(&:id).include?(ids.last).should be_true
63
+ end
64
+
65
+ it "should not return archived result when false" do
66
+ item_one = Item.create(:name => 'Item One', :description => 'foo')
67
+ item_two = Item.create(:name => 'Item Two', :description => 'bar')
68
+ ids = [item_one.id, item_two.id]
69
+ item_two.destroy
70
+ lambda {Item.find(ids)}.should raise_error(ActiveRecord::RecordNotFound)
71
+ end
72
+ end
73
+
74
+ it "should archive the default to_s" do
75
+ thing_one = Thing.create(:name => 'Thing One', :description => 'foo')
76
+ t_to_s = thing_one.to_s
77
+ thing_one.destroy
78
+ archived_thing = Thing.find_archived(thing_one.id)
79
+ archived_thing.to_s.should == t_to_s
80
+ end
81
+
82
+ it "should archive a specified method" do
83
+ item_one = Item.create(:name => 'Item One', :description => 'foo')
84
+ i_to_s = item_one.archive_value
85
+ item_one.destroy
86
+ archived_thing = Item.find_archived(item_one.id)
87
+ archived_thing.archive_value.should == i_to_s
88
+ end
89
+
90
+ it "should return a readonly AR model" do
91
+ item_one = Item.create(:name => 'Item One', :description => 'foo')
92
+ item_one.destroy
93
+ archived_thing = Item.find_archived(item_one.id)
94
+ archived_thing.readonly?.should be_true
95
+ end
96
+
97
+ #reload should do nothing, not sure how to test that though
98
+
99
+ end
@@ -0,0 +1,44 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'active_record'
4
+ require 'action_controller'
5
+ require 'rspec'
6
+ require 'archive_2s'
7
+ require 'sqlite3'
8
+
9
+ # Requires supporting files with custom matchers and macros, etc,
10
+ # in ./support/ and its subdirectories.
11
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
12
+
13
+ RSpec.configure do |config|
14
+
15
+ end
16
+
17
+ #ActiveRecord::Schema.verbose = false
18
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
19
+
20
+ ActiveRecord::Base.configurations = true
21
+ ActiveRecord::Schema.define(:version => 1) do
22
+ create_table :items do |t|
23
+ t.datetime :created_at
24
+ t.datetime :updated_at
25
+ t.string :name
26
+ t.string :description
27
+ end
28
+
29
+ create_table :things do |t|
30
+ t.datetime :created_at
31
+ t.datetime :updated_at
32
+ t.string :name
33
+ t.string :description
34
+ end
35
+
36
+ create_table :archived_to_s do |t|
37
+ t.datetime :archived_at
38
+ t.string :model_type
39
+ t.integer :model_id
40
+ t.string :archived_value
41
+ end
42
+ add_index :archived_to_s, [:model_type,:model_id,:archived_at], :name => 'model_and_archive_date_idx', :unique => true
43
+ end
44
+
metadata ADDED
@@ -0,0 +1,200 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: archive_2s
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - SmashTank Apps, LLC
14
+ - Eric Harrison
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-11-07 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: bundler
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 23
30
+ segments:
31
+ - 1
32
+ - 0
33
+ - 0
34
+ version: 1.0.0
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: ruby-debug
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ type: :development
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: rspec
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: rails
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ type: :development
78
+ version_requirements: *id004
79
+ - !ruby/object:Gem::Dependency
80
+ name: sqlite3
81
+ prerelease: false
82
+ requirement: &id005 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ hash: 3
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ type: :development
92
+ version_requirements: *id005
93
+ - !ruby/object:Gem::Dependency
94
+ name: rcov
95
+ prerelease: false
96
+ requirement: &id006 !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ hash: 3
102
+ segments:
103
+ - 0
104
+ version: "0"
105
+ type: :development
106
+ version_requirements: *id006
107
+ description: Sometimes you just need a descriptive value of an item you are archiving. This is what archive_2s was made for.
108
+ email:
109
+ - dev@smashtankapps.com
110
+ executables:
111
+ - autospec
112
+ - erubis
113
+ - htmldiff
114
+ - ldiff
115
+ - rackup
116
+ - rails
117
+ - rake
118
+ - rake2thor
119
+ - rcov
120
+ - rdebug
121
+ - rdoc
122
+ - ri
123
+ - rspec
124
+ - thor
125
+ - tilt
126
+ - tt
127
+ extensions: []
128
+
129
+ extra_rdoc_files: []
130
+
131
+ files:
132
+ - .gitignore
133
+ - .rvmrc
134
+ - Gemfile
135
+ - Gemfile.lock
136
+ - LICENSE.txt
137
+ - README.rdoc
138
+ - Rakefile
139
+ - archive_2s.gemspec
140
+ - bin/autospec
141
+ - bin/erubis
142
+ - bin/htmldiff
143
+ - bin/ldiff
144
+ - bin/rackup
145
+ - bin/rails
146
+ - bin/rake
147
+ - bin/rake2thor
148
+ - bin/rcov
149
+ - bin/rdebug
150
+ - bin/rdoc
151
+ - bin/ri
152
+ - bin/rspec
153
+ - bin/thor
154
+ - bin/tilt
155
+ - bin/tt
156
+ - generators/archive_2s_model/archive_2s_model_generator.rb
157
+ - generators/archive_2s_model/templates/create_archive_2s_model.rb
158
+ - init.rb
159
+ - lib/archive_2s.rb
160
+ - lib/archive_2s/model.rb
161
+ - lib/archive_2s/version.rb
162
+ - spec/archive_2s_spec.rb
163
+ - spec/spec_helper.rb
164
+ homepage: http://rubygems.org/gems/archive_2s
165
+ licenses: []
166
+
167
+ post_install_message:
168
+ rdoc_options: []
169
+
170
+ require_paths:
171
+ - lib
172
+ required_ruby_version: !ruby/object:Gem::Requirement
173
+ none: false
174
+ requirements:
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ hash: 3
178
+ segments:
179
+ - 0
180
+ version: "0"
181
+ required_rubygems_version: !ruby/object:Gem::Requirement
182
+ none: false
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ hash: 23
187
+ segments:
188
+ - 1
189
+ - 3
190
+ - 6
191
+ version: 1.3.6
192
+ requirements: []
193
+
194
+ rubyforge_project: archive_2s
195
+ rubygems_version: 1.8.10
196
+ signing_key:
197
+ specification_version: 3
198
+ summary: A little gem that will archive the to_s of ActiveRecord Models
199
+ test_files: []
200
+