summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2014-12-05 08:03:32 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2014-12-05 08:03:32 +0000
commit7673910a2d9f90ddc27eb2be48bb2e46eda59450 (patch)
tree863b3cd7f7068bc924c639ceb3cbce6d851dcf45 /app
parent85765a39e4fba89cf57cba90612e33ad3e478781 (diff)
downloadredmine-7673910a2d9f90ddc27eb2be48bb2e46eda59450.tar.gz
redmine-7673910a2d9f90ddc27eb2be48bb2e46eda59450.zip
Moved journal details generation to Journal model.
git-svn-id: http://svn.redmine.org/redmine/trunk@13703 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app')
-rw-r--r--app/models/issue.rb98
-rw-r--r--app/models/journal.rb102
2 files changed, 122 insertions, 78 deletions
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 22dca5212..0a72b983d 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -687,14 +687,6 @@ class Issue < ActiveRecord::Base
def init_journal(user, notes = "")
@current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
- if new_record?
- @current_journal.notify = false
- else
- @attributes_before_change = attributes.dup
- @custom_values_before_change = {}
- self.custom_field_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
- end
- @current_journal
end
# Returns the current journal or nil if it's not initialized
@@ -702,6 +694,11 @@ class Issue < ActiveRecord::Base
@current_journal
end
+ # Returns the names of attributes that are journalized when updating the issue
+ def journalized_attribute_names
+ Issue.column_names - %w(id root_id lft rgt lock_version created_on updated_on closed_on)
+ end
+
# Returns the id of the last journal or nil
def last_journal_id
if new_record?
@@ -1522,41 +1519,33 @@ class Issue < ActiveRecord::Base
end
# Callback on file attachment
- def attachment_added(obj)
- if @current_journal && !obj.new_record?
- @current_journal.details << JournalDetail.new(:property => 'attachment', :prop_key => obj.id, :value => obj.filename)
+ def attachment_added(attachment)
+ if current_journal && !attachment.new_record?
+ current_journal.journalize_attachment(attachment, :added)
end
end
# Callback on attachment deletion
- def attachment_removed(obj)
- if @current_journal && !obj.new_record?
- @current_journal.details << JournalDetail.new(:property => 'attachment', :prop_key => obj.id, :old_value => obj.filename)
- @current_journal.save
+ def attachment_removed(attachment)
+ if current_journal && !attachment.new_record?
+ current_journal.journalize_attachment(attachment, :removed)
+ current_journal.save
end
end
# Called after a relation is added
def relation_added(relation)
- if @current_journal
- @current_journal.details << JournalDetail.new(
- :property => 'relation',
- :prop_key => relation.relation_type_for(self),
- :value => relation.other_issue(self).try(:id)
- )
- @current_journal.save
+ if current_journal
+ current_journal.journalize_relation(relation, :added)
+ current_journal.save
end
end
# Called after a relation is removed
def relation_removed(relation)
- if @current_journal
- @current_journal.details << JournalDetail.new(
- :property => 'relation',
- :prop_key => relation.relation_type_for(self),
- :old_value => relation.other_issue(self).try(:id)
- )
- @current_journal.save
+ if current_journal
+ current_journal.journalize_relation(relation, :removed)
+ current_journal.save
end
end
@@ -1616,55 +1605,8 @@ class Issue < ActiveRecord::Base
# Saves the changes in a Journal
# Called after_save
def create_journal
- if @current_journal
- # attributes changes
- if @attributes_before_change
- (Issue.column_names - %w(id root_id lft rgt lock_version created_on updated_on closed_on)).each {|c|
- before = @attributes_before_change[c]
- after = send(c)
- next if before == after || (before.blank? && after.blank?)
- @current_journal.details << JournalDetail.new(:property => 'attr',
- :prop_key => c,
- :old_value => before,
- :value => after)
- }
- end
- if @custom_values_before_change
- # custom fields changes
- custom_field_values.each {|c|
- before = @custom_values_before_change[c.custom_field_id]
- after = c.value
- next if before == after || (before.blank? && after.blank?)
-
- if before.is_a?(Array) || after.is_a?(Array)
- before = [before] unless before.is_a?(Array)
- after = [after] unless after.is_a?(Array)
-
- # values removed
- (before - after).reject(&:blank?).each do |value|
- @current_journal.details << JournalDetail.new(:property => 'cf',
- :prop_key => c.custom_field_id,
- :old_value => value,
- :value => nil)
- end
- # values added
- (after - before).reject(&:blank?).each do |value|
- @current_journal.details << JournalDetail.new(:property => 'cf',
- :prop_key => c.custom_field_id,
- :old_value => nil,
- :value => value)
- end
- else
- @current_journal.details << JournalDetail.new(:property => 'cf',
- :prop_key => c.custom_field_id,
- :old_value => before,
- :value => after)
- end
- }
- end
- @current_journal.save
- # reset current journal
- init_journal @current_journal.user, @current_journal.notes
+ if current_journal
+ current_journal.save
end
end
diff --git a/app/models/journal.rb b/app/models/journal.rb
index 770e98585..681bd9b94 100644
--- a/app/models/journal.rb
+++ b/app/models/journal.rb
@@ -50,7 +50,16 @@ class Journal < ActiveRecord::Base
where("(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(user, :view_private_notes, *args)}))", false)
}
+ def initialize(*args)
+ super
+ if journalized && journalized.new_record?
+ self.notify = false
+ end
+ start
+ end
+
def save(*args)
+ journalize_changes
# Do not save an empty journal
(details.empty? && notes.blank?) ? false : super
end
@@ -166,8 +175,101 @@ class Journal < ActiveRecord::Base
journals
end
+ # Stores the values of the attributes and custom fields of the journalized object
+ def start
+ if journalized
+ @attributes_before_change = journalized.journalized_attribute_names.inject({}) do |h, attribute|
+ h[attribute] = journalized.send(attribute)
+ h
+ end
+ @custom_values_before_change = journalized.custom_field_values.inject({}) do |h, c|
+ h[c.custom_field_id] = c.value
+ h
+ end
+ end
+ self
+ end
+
+ # Adds a journal detail for an attachment that was added or removed
+ def journalize_attachment(attachment, added_or_removed)
+ key = (added_or_removed == :removed ? :old_value : :value)
+ details << JournalDetail.new(
+ :property => 'attachment',
+ :prop_key => attachment.id,
+ key => attachment.filename
+ )
+ end
+
+ # Adds a journal detail for an issue relation that was added or removed
+ def journalize_relation(relation, added_or_removed)
+ key = (added_or_removed == :removed ? :old_value : :value)
+ details << JournalDetail.new(
+ :property => 'relation',
+ :prop_key => relation.relation_type_for(journalized),
+ key => relation.other_issue(journalized).try(:id)
+ )
+ end
+
private
+ # Generates journal details for attribute and custom field changes
+ def journalize_changes
+ # attributes changes
+ if @attributes_before_change
+ journalized.journalized_attribute_names.each {|attribute|
+ before = @attributes_before_change[attribute]
+ after = journalized.send(attribute)
+ next if before == after || (before.blank? && after.blank?)
+ add_attribute_detail(attribute, before, after)
+ }
+ end
+ if @custom_values_before_change
+ # custom fields changes
+ journalized.custom_field_values.each {|c|
+ before = @custom_values_before_change[c.custom_field_id]
+ after = c.value
+ next if before == after || (before.blank? && after.blank?)
+
+ if before.is_a?(Array) || after.is_a?(Array)
+ before = [before] unless before.is_a?(Array)
+ after = [after] unless after.is_a?(Array)
+
+ # values removed
+ (before - after).reject(&:blank?).each do |value|
+ add_custom_value_detail(c, value, nil)
+ end
+ # values added
+ (after - before).reject(&:blank?).each do |value|
+ add_custom_value_detail(c, nil, value)
+ end
+ else
+ add_custom_value_detail(c, before, after)
+ end
+ }
+ end
+ start
+ end
+
+ # Adds a journal detail for an attribute change
+ def add_attribute_detail(attribute, old_value, value)
+ add_detail('attr', attribute, old_value, value)
+ end
+
+ # Adds a journal detail for a custom field value change
+ def add_custom_value_detail(custom_value, old_value, value)
+ add_detail('cf', custom_value.custom_field_id, old_value, value)
+ end
+
+ # Adds a journal detail
+ def add_detail(property, prop_key, old_value, value)
+ details << JournalDetail.new(
+ :property => property,
+ :prop_key => prop_key,
+ :old_value => old_value,
+ :value => value
+ )
+ end
+
def split_private_notes
if private_notes?
if notes.present?