Skip to content

Commit

Permalink
Moving ActsAsArchive configuration to YAML file (config/acts_as_archi…
Browse files Browse the repository at this point in the history
…ve.yml)
  • Loading branch information
winton committed Jan 26, 2011
1 parent bb9f9ef commit dd7b490
Show file tree
Hide file tree
Showing 12 changed files with 120 additions and 49 deletions.
28 changes: 16 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,29 @@ gem 'acts_as_archive'

<pre>
require 'acts_as_archive'
</pre>

Add to models
-------------
class Application &lt; Sinatra::Base
include ActsAsArchive::Adapters::Sinatra
end
</pre>

Add <code>acts\_as\_archive</code> to your models:
config/acts\_as\_archive.yml
----------------------------

<pre>
class Article &lt; ActiveRecord::Base
acts_as_archive
end
Article:
- class: Article::Archive
table: archived_articles
</pre>

Specify the name of your model, the name of the archive class, and the name of the archive table.

If the archive model is created automatically if it does not exist.

Migrate
-------

Next time you run <code>rake db:migrate</code>, your archive tables will be created automatically.
Run <code>rake db:migrate</code>. Your archive table is created automatically.

That's it!
----------
Expand All @@ -60,9 +66,7 @@ Records move into the archive table instead of being destroyed.
Automatically archive relationships
-----------------------------------

If your <code>acts\_as\_archive</code> model's relationship has the <code>:dependent</code> option and also uses <code>acts\_as\_archive</code>, that relationship will archive automatically.

__To use this feature, you must declare your relationships before the <code>acts\_as\_archive</code> call within your model!__
If your model's relationship has the <code>:dependent</code> option, and the relationship also uses <code>acts\_as\_archive</code>, that relationship will archive automatically.

What if my schema changes?
--------------------------
Expand All @@ -74,7 +78,7 @@ No action is necessary on your part.
Query the archive
-----------------

Add <code>::Archive</code> to your ActiveRecord class:
Use the Archive model you specified in the configuration:

<pre>
Article::Archive.first
Expand Down
2 changes: 1 addition & 1 deletion config/gemsets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ acts_as_archive:
externals: =1.0.2
framework_fixture: =0.1.3
mover: =0.3.6
rack-test: =0.5.7
rack-test: =0.5.6
98 changes: 66 additions & 32 deletions lib/acts_as_archive.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

require 'also_migrate'
require 'mover'
require 'yaml'

$:.unshift File.dirname(__FILE__)

Expand Down Expand Up @@ -41,18 +42,34 @@ def find(from)
end
end

def move(config, where, merge_options={})
config[:to].each do |to|
options = config[:options].dup.merge(merge_options)
if options[:conditions]
options[:conditions] += " AND #{where}"
elsif where
options[:conditions] = where
def load_from_yaml(root)
if File.exists?(yaml = "#{root}/config/acts_as_archive.yml")
YAML.load(File.read(yaml)).each do |klass, config|
klass = eval(klass) rescue nil
if klass
if (%w(class table) - config.last.keys).empty?
options = {}
else
options = config.pop
end
config.each do |c|
klass.acts_as_archive options.merge(c)
end
end
end
config[:from].move_to(to, options)
end
end

def move(config, where, merge_options={})
options = config[:options].dup.merge(merge_options)
if options[:conditions]
options[:conditions] += " AND #{where}"
elsif where
options[:conditions] = where
end
config[:from].move_to(config[:to], options)
end

def update(*args)
deprecate "ActsAsArchive.update is deprecated and no longer necessary."
end
Expand All @@ -67,53 +84,67 @@ def self.included(base)
end

module ClassMethods
def acts_as_archive(*args)
def acts_as_archive(options={})
return unless ActsAsArchive.find(self).empty?

ActsAsArchive.configuration ||= []
ActsAsArchive.configuration << (config = { :from => self })

options = args.last.is_a?(::Hash) ? args.pop : {}
options[:copy] = true

if options[:archive]
options[:magic] = 'restored_at'
klass = options[:class]
else
options[:magic] = 'deleted_at' if options[:magic].nil?
options[:add] = [[ options[:magic], :datetime ]]
options[:ignore] = options[:magic]
options[:subtract] = 'restored_at'
options[:timestamps] = false if options[:timestamps].nil?

if args.empty?
class_eval <<-EVAL
class Archive < ActiveRecord::Base
set_table_name "archived_#{self.table_name}"
unless options[:class]
options[:class] = "#{self}::Archive"
end

unless options[:table]
options[:table] = "archived_#{self.table_name}"
end

klass = eval(options[:class]) rescue nil

if klass
klass.send :set_table_name, options[:table]
else
eval <<-EVAL
class ::#{options[:class]} < ActiveRecord::Base
set_table_name "#{options[:table]}"
end
EVAL
args << self::Archive
klass = eval("::#{options[:class]}")
end

klass.record_timestamps = options[:timestamps].inspect
klass.acts_as_archive(:class => self, :archive => true)

args.each do |klass|
klass.class_eval <<-EVAL
record_timestamps = #{options[:timestamps].inspect}
acts_as_archive(#{self}, :archive => true)
EVAL
self.reflect_on_all_associations.each do |association|
if !ActsAsArchive.find(association.klass).empty? && association.options[:dependent]
opts = association.options.dup
opts[:class_name] = "::#{association.class_name}::Archive"
opts[:foreign_key] = association.primary_key_name
klass.send association.macro, association.name, opts
end
end
unless options[:migrate] == false
self.also_migrate klass.table_name, options
self.reflect_on_all_associations.each do |association|
if !ActsAsArchive.find(association.klass).empty? && association.options[:dependent]
opts = association.options.dup
opts[:class_name] = "::#{association.class_name}::Archive"
opts[:foreign_key] = association.primary_key_name
klass.send association.macro, association.name, opts
end
end

unless options[:migrate] == false
AlsoMigrate.configuration ||= []
AlsoMigrate.configuration << options.merge(
:source => self.table_name,
:destination => klass.table_name
)
end
end

config[:to] = args
config[:to] = klass
config[:options] = options
end

Expand Down Expand Up @@ -192,4 +223,7 @@ def delete_sql_with_archive(sql, name = nil)
end

::ActiveRecord::Base.send(:include, ::ActsAsArchive::Base)
::ActiveRecord::ConnectionAdapters::DatabaseStatements.send(:include, ::ActsAsArchive::DatabaseStatements)
::ActiveRecord::ConnectionAdapters::DatabaseStatements.send(:include, ::ActsAsArchive::DatabaseStatements)

require "acts_as_archive/adapters/rails#{Rails.version[0..0]}" if defined?(Rails)
require "acts_as_archive/adapters/sinatra" if defined?(Sinatra)
1 change: 1 addition & 0 deletions lib/acts_as_archive/adapters/rails2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ActsAsArchive.load_from_yaml(Rails.root)
9 changes: 9 additions & 0 deletions lib/acts_as_archive/adapters/rails3.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
if Rails.root.nil?
class ActsAsArchiveRailtie < Rails::Railtie
initializer "acts_as_archive" do
ActsAsArchive.load_from_yaml(Rails.root)
end
end
else
ActsAsArchive.load_from_yaml(Rails.root)
end
12 changes: 12 additions & 0 deletions lib/acts_as_archive/adapters/sinatra.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class ActsAsArchive
module Adapters
module Sinatra

def self.included(klass)
if klass.root
ActsAsArchive.load_from_yaml(klass.root)
end
end
end
end
end
3 changes: 3 additions & 0 deletions spec/fixtures/config/acts_as_archive.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Record:
- class: Record::Archive
table: archived_records
5 changes: 5 additions & 0 deletions spec/fixtures/frameworks.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
rails:
<3:
config: &c
- config/acts_as_archive.yml
frameworks/rails2:
- app/controllers/application_controller.rb
- config/database.yml
Expand All @@ -17,6 +19,7 @@ rails:
- app/models/has_one_through_through.rb
- app/models/record.rb
<4:
config: *c
frameworks/rails3:
- app/controllers/application_controller.rb
- config/database.yml
Expand All @@ -26,11 +29,13 @@ rails:
models: *m
sinatra:
<1:
config: *c
frameworks/sinatra: &s
- application.rb
helpers: *h
models: *m
<2:
config: *c
frameworks/sinatra: *s
helpers: *h
models: *m
2 changes: 2 additions & 0 deletions spec/fixtures/frameworks/rails3/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ gem 'mysql2'
gem 'rails', '3.0.3'
gem 'rspec'

gem 'also_migrate', :path => "../../../../vendor/also_migrate"
gem 'mover', :path => "../../../../vendor/mover"
gem 'acts_as_archive', :path => "../../../../"

# Bundle edge Rails instead:
Expand Down
1 change: 1 addition & 0 deletions spec/fixtures/frameworks/sinatra/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Application < Sinatra::Base
set :raise_errors, true
set :show_exceptions, false

include ActsAsArchive::Adapters::Sinatra
include SpecHelper

get '/pulse' do
Expand Down
2 changes: 0 additions & 2 deletions spec/fixtures/models/record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,4 @@ class Record < ActiveRecord::Base

has_one :has_one_through_through, :dependent => :destroy
has_one :has_one_through, :dependent => :destroy, :through => :has_one_through_through

acts_as_archive
end
6 changes: 4 additions & 2 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@
ActiveSupport::Dependencies.autoload_paths << "#{$root}/spec/fixtures/models"
ActiveSupport::Dependencies.autoload_paths << "#{$root}/spec/fixtures/helpers"

Record # Load up an instance so first also_migrate works

include SpecHelper
end

Expand All @@ -57,6 +55,10 @@
)
$db.establish_connection

unless FrameworkFixture.framework
ActsAsArchive.load_from_yaml("#{$root}/spec/fixtures")
end

if FrameworkFixture.framework == 'sinatra'
FrameworkFixture.generate File.dirname(__FILE__) + '/fixtures'
end
Expand Down

0 comments on commit dd7b490

Please sign in to comment.