[#445] Track initial object attributes on the initial journal

So the initial journal would have the changes from an Object#new
to the created version of the Object. Also includes a change to the
database migration in order to create these initial journals for
all journaled Objects.
This commit is contained in:
Eric Davis 2011-06-03 13:01:56 -07:00
parent 3b64c60bc0
commit 33e3a71341
3 changed files with 65 additions and 21 deletions

View File

@ -46,6 +46,49 @@ class GeneralizeJournals < ActiveRecord::Migration
t.remove :journalized_type
end
# Build initial journals for all activity providers
providers = Redmine::Activity.providers.collect {|k, v| v.collect(&:constantize) }.flatten.compact.uniq
providers.each do |p|
next unless p.table_exists? # Objects not in the DB yet need creation journal entries
p.find(:all).each do |o|
# Create initial journals
new_journal = o.journals.build
# Mock up a list of changes for the creation journal based on Class defaults
new_attributes = o.class.new.attributes.except(o.class.primary_key,
o.class.inheritance_column,
:updated_on,
:updated_at,
:lock_version,
:lft,
:rgt)
creation_changes = {}
new_attributes.each do |name, default_value|
# Set changes based on the initial value to current. Can't get creation value without
# rebuiling the object history
creation_changes[name] = [default_value, o.send(name)] # [initial_value, creation_value]
end
new_journal.changes = creation_changes
new_journal.version = 1
if o.respond_to?(:author)
new_journal.user = o.author
elsif o.respond_to?(:user)
new_journal.user = o.user
end
new_journal.save
# Backdate journal
if o.respond_to?(:created_at)
new_journal.update_attribute(:created_at, o.created_at)
elsif o.respond_to?(:created_on)
new_journal.update_attribute(:created_at, o.created_on)
end
p "Updating #{o}"
end
end
# Migrate journal changes now
JournalDetails.all.each do |detail|
journal = Journal.find(detail.journal_id)
changes = journal.changes || {}
@ -59,26 +102,6 @@ class GeneralizeJournals < ActiveRecord::Migration
journal.update_attribute(:changes, changes.to_yaml)
end
# Create creation journals for all activity providers
providers = Redmine::Activity.providers.collect {|k, v| v.collect(&:constantize) }.flatten.compact.uniq
providers.each do |p|
next unless p.table_exists? # Objects not in the DB yet need creation journal entries
p.find(:all).each do |o|
unless o.last_journal
o.send(:update_journal)
created_at = nil
[:created_at, :created_on, :updated_at, :updated_on].each do |m|
if o.respond_to? m
created_at = o.send(m)
break
end
end
p "Updating #{o}"
o.last_journal.update_attribute(:created_at, created_at) if created_at and o.last_journal
end
end
end
# drop_table :journal_details
end

View File

@ -58,4 +58,25 @@ class JournalTest < ActiveSupport::TestCase
end
assert_equal 0, ActionMailer::Base.deliveries.size
end
test "creating the initial journal should track the changes from creation" do
@project = Project.generate!
issue = Issue.new do |i|
i.project = @project
i.subject = "Test initial journal"
i.tracker = @project.trackers.first
i.author = User.generate!
i.description = "Some content"
end
assert_difference("Journal.count") do
assert issue.save
end
journal = issue.reload.journals.first
assert_equal ["","Test initial journal"], journal.changes["subject"]
assert_equal [0, @project.id], journal.changes["project_id"]
assert_equal [nil, "Some content"], journal.changes["description"]
end
end

View File

@ -45,7 +45,7 @@ module Redmine::Acts::Journalized
base.class_eval do
include InstanceMethods
after_update :merge_journal_changes
after_save :merge_journal_changes
end
end