summaryrefslogtreecommitdiffstats
path: root/app/models
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2017-07-23 11:26:04 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2017-07-23 11:26:04 +0000
commitd74f0bfd5c53962e332c2dd4d30dafaa1105b92b (patch)
treef3eaf66d67c3a87fb34340561bf188d364de623c /app/models
parent41bb302594b48152b87c92f196c915f499093bbf (diff)
downloadredmine-d74f0bfd5c53962e332c2dd4d30dafaa1105b92b.tar.gz
redmine-d74f0bfd5c53962e332c2dd4d30dafaa1105b92b.zip
Merged rails-5.1 branch (#23630).
git-svn-id: http://svn.redmine.org/redmine/trunk@16859 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app/models')
-rw-r--r--app/models/attachment.rb1
-rw-r--r--app/models/auth_source.rb1
-rw-r--r--app/models/board.rb1
-rw-r--r--app/models/change.rb1
-rw-r--r--app/models/changeset.rb1
-rw-r--r--app/models/comment.rb1
-rw-r--r--app/models/custom_field.rb5
-rw-r--r--app/models/custom_value.rb1
-rw-r--r--app/models/document.rb1
-rw-r--r--app/models/email_address.rb11
-rw-r--r--app/models/enabled_module.rb1
-rw-r--r--app/models/enumeration.rb4
-rw-r--r--app/models/group.rb1
-rw-r--r--app/models/issue.rb67
-rw-r--r--app/models/issue_category.rb1
-rw-r--r--app/models/issue_custom_field.rb4
-rw-r--r--app/models/issue_priority.rb2
-rw-r--r--app/models/issue_relation.rb5
-rw-r--r--app/models/issue_status.rb3
-rw-r--r--app/models/journal.rb1
-rw-r--r--app/models/journal_detail.rb1
-rw-r--r--app/models/member.rb1
-rw-r--r--app/models/member_role.rb1
-rw-r--r--app/models/message.rb5
-rw-r--r--app/models/news.rb1
-rw-r--r--app/models/project.rb25
-rw-r--r--app/models/query.rb6
-rw-r--r--app/models/repository.rb1
-rw-r--r--app/models/repository/bazaar.rb1
-rw-r--r--app/models/repository/filesystem.rb1
-rw-r--r--app/models/repository/git.rb1
-rw-r--r--app/models/repository/mercurial.rb1
-rw-r--r--app/models/repository/subversion.rb1
-rw-r--r--app/models/role.rb1
-rw-r--r--app/models/setting.rb1
-rw-r--r--app/models/time_entry.rb2
-rw-r--r--app/models/token.rb1
-rw-r--r--app/models/tracker.rb2
-rw-r--r--app/models/user.rb19
-rw-r--r--app/models/user_preference.rb2
-rw-r--r--app/models/version.rb7
-rw-r--r--app/models/watcher.rb1
-rw-r--r--app/models/wiki.rb1
-rw-r--r--app/models/wiki_content.rb6
-rw-r--r--app/models/wiki_page.rb7
-rw-r--r--app/models/wiki_redirect.rb1
-rw-r--r--app/models/workflow_rule.rb1
47 files changed, 81 insertions, 130 deletions
diff --git a/app/models/attachment.rb b/app/models/attachment.rb
index eea80132c..b967e5720 100644
--- a/app/models/attachment.rb
+++ b/app/models/attachment.rb
@@ -28,7 +28,6 @@ class Attachment < ActiveRecord::Base
validates_length_of :disk_filename, :maximum => 255
validates_length_of :description, :maximum => 255
validate :validate_max_file_size, :validate_file_extension
- attr_protected :id
acts_as_event :title => :filename,
:url => Proc.new {|o| {:controller => 'attachments', :action => 'show', :id => o.id, :filename => o.filename}}
diff --git a/app/models/auth_source.rb b/app/models/auth_source.rb
index 4954c962d..c28a33fb2 100644
--- a/app/models/auth_source.rb
+++ b/app/models/auth_source.rb
@@ -30,7 +30,6 @@ class AuthSource < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name
validates_length_of :name, :maximum => 60
- attr_protected :id
safe_attributes 'name',
'host',
diff --git a/app/models/board.rb b/app/models/board.rb
index 21461e32f..7f09fddbe 100644
--- a/app/models/board.rb
+++ b/app/models/board.rb
@@ -28,7 +28,6 @@ class Board < ActiveRecord::Base
validates_length_of :name, :maximum => 30
validates_length_of :description, :maximum => 255
validate :validate_board
- attr_protected :id
scope :visible, lambda {|*args|
joins(:project).
diff --git a/app/models/change.rb b/app/models/change.rb
index e0d25f3a9..ce75239f1 100644
--- a/app/models/change.rb
+++ b/app/models/change.rb
@@ -21,7 +21,6 @@ class Change < ActiveRecord::Base
validates_presence_of :changeset_id, :action, :path
before_save :init_path
before_validation :replace_invalid_utf8_of_path
- attr_protected :id
def replace_invalid_utf8_of_path
self.path = Redmine::CodesetUtil.replace_invalid_utf8(self.path)
diff --git a/app/models/changeset.rb b/app/models/changeset.rb
index 4256f0589..637a1819f 100644
--- a/app/models/changeset.rb
+++ b/app/models/changeset.rb
@@ -46,7 +46,6 @@ class Changeset < ActiveRecord::Base
validates_presence_of :repository_id, :revision, :committed_on, :commit_date
validates_uniqueness_of :revision, :scope => :repository_id
validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true
- attr_protected :id
scope :visible, lambda {|*args|
joins(:repository => :project).
diff --git a/app/models/comment.rb b/app/models/comment.rb
index 48b47d970..e29b574c1 100644
--- a/app/models/comment.rb
+++ b/app/models/comment.rb
@@ -21,7 +21,6 @@ class Comment < ActiveRecord::Base
belongs_to :author, :class_name => 'User'
validates_presence_of :commented, :author, :comments
- attr_protected :id
after_create :send_notification
diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb
index ca061a25f..58911b5f7 100644
--- a/app/models/custom_field.rb
+++ b/app/models/custom_field.rb
@@ -35,7 +35,6 @@ class CustomField < ActiveRecord::Base
validates_length_of :regexp, maximum: 255
validates_inclusion_of :field_format, :in => Proc.new { Redmine::FieldFormat.available_formats }
validate :validate_custom_field
- attr_protected :id
before_validation :set_searchable
before_save do |field|
@@ -43,7 +42,7 @@ class CustomField < ActiveRecord::Base
end
after_save :handle_multiplicity_change
after_save do |field|
- if field.visible_changed? && field.visible
+ if field.saved_change_to_visible? && field.visible
field.roles.clear
end
end
@@ -316,7 +315,7 @@ class CustomField < ActiveRecord::Base
# Removes multiple values for the custom field after setting the multiple attribute to false
# We kepp the value with the highest id for each customized object
def handle_multiplicity_change
- if !new_record? && multiple_was && !multiple
+ if !new_record? && multiple_before_last_save && !multiple
ids = custom_values.
where("EXISTS(SELECT 1 FROM #{CustomValue.table_name} cve WHERE cve.custom_field_id = #{CustomValue.table_name}.custom_field_id" +
" AND cve.customized_type = #{CustomValue.table_name}.customized_type AND cve.customized_id = #{CustomValue.table_name}.customized_id" +
diff --git a/app/models/custom_value.rb b/app/models/custom_value.rb
index b649ec81d..9a5610930 100644
--- a/app/models/custom_value.rb
+++ b/app/models/custom_value.rb
@@ -18,7 +18,6 @@
class CustomValue < ActiveRecord::Base
belongs_to :custom_field
belongs_to :customized, :polymorphic => true
- attr_protected :id
after_save :custom_field_after_save_custom_value
diff --git a/app/models/document.rb b/app/models/document.rb
index d347e583c..8e4b15517 100644
--- a/app/models/document.rb
+++ b/app/models/document.rb
@@ -31,7 +31,6 @@ class Document < ActiveRecord::Base
validates_presence_of :project, :title, :category
validates_length_of :title, :maximum => 255
- attr_protected :id
after_create :send_notification
diff --git a/app/models/email_address.rb b/app/models/email_address.rb
index 295b9bcaa..d144e2f88 100644
--- a/app/models/email_address.rb
+++ b/app/models/email_address.rb
@@ -19,7 +19,6 @@ class EmailAddress < ActiveRecord::Base
include Redmine::SafeAttributes
belongs_to :user
- attr_protected :id
after_create :deliver_security_notification_create
after_update :destroy_tokens, :deliver_security_notification_update
@@ -63,17 +62,17 @@ class EmailAddress < ActiveRecord::Base
# send a security notification to user that an email has been changed (notified/not notified)
def deliver_security_notification_update
- if address_changed?
- recipients = [user, address_was]
+ if saved_change_to_address?
+ recipients = [user, address_before_last_save]
options = {
message: :mail_body_security_notification_change_to,
field: :field_mail,
value: address
}
- elsif notify_changed?
+ elsif saved_change_to_notify?
recipients = [user, address]
options = {
- message: notify_was ? :mail_body_security_notification_notify_disabled : :mail_body_security_notification_notify_enabled,
+ message: notify_before_last_save ? :mail_body_security_notification_notify_disabled : :mail_body_security_notification_notify_enabled,
value: address
}
end
@@ -103,7 +102,7 @@ class EmailAddress < ActiveRecord::Base
# This helps to keep the account secure in case the associated email account
# was compromised.
def destroy_tokens
- if address_changed? || destroyed?
+ if saved_change_to_address? || destroyed?
tokens = ['recovery']
Token.where(:user_id => user_id, :action => tokens).delete_all
end
diff --git a/app/models/enabled_module.rb b/app/models/enabled_module.rb
index 2548ba25d..12511662c 100644
--- a/app/models/enabled_module.rb
+++ b/app/models/enabled_module.rb
@@ -21,7 +21,6 @@ class EnabledModule < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name, :scope => :project_id
- attr_protected :id
after_create :module_enabled
diff --git a/app/models/enumeration.rb b/app/models/enumeration.rb
index eef691c4c..f330da085 100644
--- a/app/models/enumeration.rb
+++ b/app/models/enumeration.rb
@@ -29,8 +29,6 @@ class Enumeration < ActiveRecord::Base
before_destroy :check_integrity
before_save :check_default
- attr_protected :type
-
validates_presence_of :name
validates_uniqueness_of :name, :scope => [:type, :project_id]
validates_length_of :name, :maximum => 30
@@ -148,7 +146,7 @@ class Enumeration < ActiveRecord::Base
# position as the overridden enumeration
def update_position
super
- if position_changed?
+ if saved_change_to_position?
self.class.where.not(:parent_id => nil).update_all(
"position = coalesce((
select position
diff --git a/app/models/group.rb b/app/models/group.rb
index d94ef753c..b81e877af 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -28,7 +28,6 @@ class Group < Principal
validates_presence_of :lastname
validates_uniqueness_of :lastname, :case_sensitive => false
validates_length_of :lastname, :maximum => 255
- attr_protected :id
self.valid_statuses = [STATUS_ACTIVE]
diff --git a/app/models/issue.rb b/app/models/issue.rb
index f984e0332..5798fef9f 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -69,7 +69,6 @@ class Issue < ActiveRecord::Base
validates :start_date, :date => true
validates :due_date, :date => true
validate :validate_issue, :validate_required_fields, :validate_permissions
- attr_protected :id
scope :visible, lambda {|*args|
joins(:project).
@@ -108,16 +107,14 @@ class Issue < ActiveRecord::Base
before_validation :default_assign, on: :create
before_validation :clear_disabled_fields
before_save :close_duplicates, :update_done_ratio_from_issue_status,
- :force_updated_on_change, :update_closed_on, :set_assigned_to_was
- after_save {|issue| issue.send :after_project_change if !issue.id_changed? && issue.project_id_changed?}
+ :force_updated_on_change, :update_closed_on
+ after_save {|issue| issue.send :after_project_change if !issue.saved_change_to_id? && issue.saved_change_to_project_id?}
after_save :reschedule_following_issues, :update_nested_set_attributes,
:update_parent_attributes, :delete_selected_attachments, :create_journal
# Should be after_create but would be called before previous after_save callbacks
after_save :after_create_from_copy
after_destroy :update_parent_attributes
after_create :send_notification
- # Keep it at the end of after_save callbacks
- after_save :clear_assigned_to_was
# Returns a SQL conditions string used to find all issues visible by the specified user
def self.visible_condition(user, options={})
@@ -208,7 +205,7 @@ class Issue < ActiveRecord::Base
end
end
- def create_or_update
+ def create_or_update(*args)
super
ensure
@status_was = nil
@@ -512,6 +509,10 @@ class Issue < ActiveRecord::Base
# attr_accessible is too rough because we still want things like
# Issue.new(:project => foo) to work
def safe_attributes=(attrs, user=User.current)
+ if attrs.respond_to?(:to_unsafe_hash)
+ attrs = attrs.to_unsafe_hash
+ end
+
@attributes_set_by = user
return unless attrs.is_a?(Hash)
@@ -586,8 +587,7 @@ class Issue < ActiveRecord::Base
attrs['custom_fields'].select! {|c| editable_custom_field_ids.include?(c['id'].to_s)}
end
- # mass-assignment security bypass
- assign_attributes attrs, :without_protection => true
+ assign_attributes attrs
end
def disabled_core_fields
@@ -1007,32 +1007,27 @@ class Issue < ActiveRecord::Base
statuses
end
- # Returns the previous assignee (user or group) if changed
- def assigned_to_was
- # assigned_to_id_was is reset before after_save callbacks
- user_id = @previous_assigned_to_id || assigned_to_id_was
- if user_id && user_id != assigned_to_id
- @assigned_to_was ||= Principal.find_by_id(user_id)
- end
- end
-
# Returns the original tracker
def tracker_was
- Tracker.find_by_id(tracker_id_was)
+ Tracker.find_by_id(tracker_id_in_database)
+ end
+
+ # Returns the previous assignee whenever we're before the save
+ # or in after_* callbacks
+ def previous_assignee
+ # This is how ActiveRecord::AttributeMethods::Dirty checks if we're in a after_* callback
+ if previous_assigned_to_id = mutation_tracker.equal?(mutations_from_database) ? assigned_to_id_in_database : assigned_to_id_before_last_save
+ Principal.find_by_id(previous_assigned_to_id)
+ end
end
# Returns the users that should be notified
def notified_users
- notified = []
# Author and assignee are always notified unless they have been
# locked or don't want to be notified
- notified << author if author
- if assigned_to
- notified += (assigned_to.is_a?(Group) ? assigned_to.users : [assigned_to])
- end
- if assigned_to_was
- notified += (assigned_to_was.is_a?(Group) ? assigned_to_was.users : [assigned_to_was])
- end
+ notified = [author, assigned_to, previous_assignee].compact.uniq
+ notified = notified.map {|n| n.is_a?(Group) ? n.users : n}.flatten
+ notified.uniq!
notified = notified.select {|u| u.active? && u.notify_about?(self)}
notified += project.notified_users
@@ -1587,7 +1582,7 @@ class Issue < ActiveRecord::Base
# Move subtasks that were in the same project
children.each do |child|
- next unless child.project_id == project_id_was
+ next unless child.project_id == project_id_before_last_save
# Change project and keep project
child.send :project=, project, true
unless child.save
@@ -1644,7 +1639,7 @@ class Issue < ActiveRecord::Base
end
def update_nested_set_attributes
- if parent_id_changed?
+ if saved_change_to_parent_id?
update_nested_set_attributes_on_parent_change
end
remove_instance_variable(:@parent_issue) if instance_variable_defined?(:@parent_issue)
@@ -1652,7 +1647,7 @@ class Issue < ActiveRecord::Base
# Updates the nested set for when an existing issue is moved
def update_nested_set_attributes_on_parent_change
- former_parent_id = parent_id_was
+ former_parent_id = parent_id_before_last_save
# delete invalid relations of all descendants
self_and_descendants.each do |issue|
issue.relations.each do |relation|
@@ -1789,7 +1784,7 @@ class Issue < ActiveRecord::Base
# Updates start/due dates of following issues
def reschedule_following_issues
- if start_date_changed? || due_date_changed?
+ if saved_change_to_start_date? || saved_change_to_due_date?
relations_from.each do |relation|
relation.set_issue_to_dates
end
@@ -1848,18 +1843,6 @@ class Issue < ActiveRecord::Base
end
end
- # Stores the previous assignee so we can still have access
- # to it during after_save callbacks (assigned_to_id_was is reset)
- def set_assigned_to_was
- @previous_assigned_to_id = assigned_to_id_was
- end
-
- # Clears the previous assignee at the end of after_save callbacks
- def clear_assigned_to_was
- @assigned_to_was = nil
- @previous_assigned_to_id = nil
- end
-
def clear_disabled_fields
if tracker
tracker.disabled_core_fields.each do |attribute|
diff --git a/app/models/issue_category.rb b/app/models/issue_category.rb
index da96a85eb..506ae483d 100644
--- a/app/models/issue_category.rb
+++ b/app/models/issue_category.rb
@@ -24,7 +24,6 @@ class IssueCategory < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name, :scope => [:project_id]
validates_length_of :name, :maximum => 60
- attr_protected :id
safe_attributes 'name', 'assigned_to_id'
diff --git a/app/models/issue_custom_field.rb b/app/models/issue_custom_field.rb
index fb7accd34..f0a7871b0 100644
--- a/app/models/issue_custom_field.rb
+++ b/app/models/issue_custom_field.rb
@@ -16,8 +16,8 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class IssueCustomField < CustomField
- has_and_belongs_to_many :projects, :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", :foreign_key => "custom_field_id"
- has_and_belongs_to_many :trackers, :join_table => "#{table_name_prefix}custom_fields_trackers#{table_name_suffix}", :foreign_key => "custom_field_id"
+ has_and_belongs_to_many :projects, :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", :foreign_key => "custom_field_id", :autosave => true
+ has_and_belongs_to_many :trackers, :join_table => "#{table_name_prefix}custom_fields_trackers#{table_name_suffix}", :foreign_key => "custom_field_id", :autosave => true
has_many :issues, :through => :issue_custom_values
safe_attributes 'project_ids',
diff --git a/app/models/issue_priority.rb b/app/models/issue_priority.rb
index 0858cbf0f..a4c93370e 100644
--- a/app/models/issue_priority.rb
+++ b/app/models/issue_priority.rb
@@ -19,7 +19,7 @@ class IssuePriority < Enumeration
has_many :issues, :foreign_key => 'priority_id'
after_destroy {|priority| priority.class.compute_position_names}
- after_save {|priority| priority.class.compute_position_names if (priority.position_changed? && priority.position) || priority.active_changed?}
+ after_save {|priority| priority.class.compute_position_names if (priority.saved_change_to_position? && priority.position) || priority.saved_change_to_active?}
OptionName = :enumeration_issue_priorities
diff --git a/app/models/issue_relation.rb b/app/models/issue_relation.rb
index d8673596c..44c7c8dba 100644
--- a/app/models/issue_relation.rb
+++ b/app/models/issue_relation.rb
@@ -72,7 +72,6 @@ class IssueRelation < ActiveRecord::Base
validates_uniqueness_of :issue_to_id, :scope => :issue_from_id
validate :validate_issue_relation
- attr_protected :issue_from_id, :issue_to_id
before_save :handle_issue_order
after_create :call_issues_relation_added_callback
after_destroy :call_issues_relation_removed_callback
@@ -82,6 +81,10 @@ class IssueRelation < ActiveRecord::Base
'issue_to_id'
def safe_attributes=(attrs, user=User.current)
+ if attrs.respond_to?(:to_unsafe_hash)
+ attrs = attrs.to_unsafe_hash
+ end
+
return unless attrs.is_a?(Hash)
attrs = attrs.deep_dup
diff --git a/app/models/issue_status.rb b/app/models/issue_status.rb
index 6d29cfc8d..9f139f2fc 100644
--- a/app/models/issue_status.rb
+++ b/app/models/issue_status.rb
@@ -30,7 +30,6 @@ class IssueStatus < ActiveRecord::Base
validates_uniqueness_of :name
validates_length_of :name, :maximum => 30
validates_inclusion_of :default_done_ratio, :in => 0..100, :allow_nil => true
- attr_protected :id
scope :sorted, lambda { order(:position) }
scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
@@ -89,7 +88,7 @@ class IssueStatus < ActiveRecord::Base
# Updates issues closed_on attribute when an existing status is set as closed.
def handle_is_closed_change
- if is_closed_changed? && is_closed == true
+ if saved_change_to_is_closed? && is_closed == true
# First we update issues that have a journal for when the current status was set,
# a subselect is used to update all issues with a single query
subquery = Journal.joins(:details).
diff --git a/app/models/journal.rb b/app/models/journal.rb
index 0d2e479ca..77823d0c2 100644
--- a/app/models/journal.rb
+++ b/app/models/journal.rb
@@ -26,7 +26,6 @@ class Journal < ActiveRecord::Base
belongs_to :user
has_many :details, :class_name => "JournalDetail", :dependent => :delete_all, :inverse_of => :journal
attr_accessor :indice
- attr_protected :id
acts_as_event :title => Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.id}#{status}: #{o.issue.subject}" },
:description => :notes,
diff --git a/app/models/journal_detail.rb b/app/models/journal_detail.rb
index f901d2702..8de9b8dbc 100644
--- a/app/models/journal_detail.rb
+++ b/app/models/journal_detail.rb
@@ -17,7 +17,6 @@
class JournalDetail < ActiveRecord::Base
belongs_to :journal
- attr_protected :id
def custom_field
if property == 'cf'
diff --git a/app/models/member.rb b/app/models/member.rb
index f9e3f5679..05bb0d441 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -25,7 +25,6 @@ class Member < ActiveRecord::Base
validates_presence_of :principal, :project
validates_uniqueness_of :user_id, :scope => :project_id
validate :validate_role
- attr_protected :id
before_destroy :set_issue_category_nil, :remove_from_project_default_assigned_to
diff --git a/app/models/member_role.rb b/app/models/member_role.rb
index 508475948..3be525363 100644
--- a/app/models/member_role.rb
+++ b/app/models/member_role.rb
@@ -26,7 +26,6 @@ class MemberRole < ActiveRecord::Base
validates_presence_of :role
validate :validate_role_member
- attr_protected :id
def validate_role_member
errors.add :role_id, :invalid if role && !role.member?
diff --git a/app/models/message.rb b/app/models/message.rb
index 65ae3148a..758095289 100644
--- a/app/models/message.rb
+++ b/app/models/message.rb
@@ -22,7 +22,6 @@ class Message < ActiveRecord::Base
acts_as_tree :counter_cache => :replies_count, :order => "#{Message.table_name}.created_on ASC"
acts_as_attachable
belongs_to :last_reply, :class_name => 'Message'
- attr_protected :id
acts_as_searchable :columns => ['subject', 'content'],
:preload => {:board => :project},
@@ -69,9 +68,9 @@ class Message < ActiveRecord::Base
end
def update_messages_board
- if board_id_changed?
+ if saved_change_to_board_id?
Message.where(["id = ? OR parent_id = ?", root.id, root.id]).update_all({:board_id => board_id})
- Board.reset_counters!(board_id_was)
+ Board.reset_counters!(board_id_before_last_save)
Board.reset_counters!(board_id)
end
end
diff --git a/app/models/news.rb b/app/models/news.rb
index 7d900d331..8243bc301 100644
--- a/app/models/news.rb
+++ b/app/models/news.rb
@@ -24,7 +24,6 @@ class News < ActiveRecord::Base
validates_presence_of :title, :description
validates_length_of :title, :maximum => 60
validates_length_of :summary, :maximum => 255
- attr_protected :id
acts_as_attachable :edit_permission => :manage_news,
:delete_permission => :manage_news
diff --git a/app/models/project.rb b/app/models/project.rb
index 7e4f4ce50..3162676b6 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -67,8 +67,6 @@ class Project < ActiveRecord::Base
:url => Proc.new {|o| {:controller => 'projects', :action => 'show', :id => o}},
:author => nil
- attr_protected :status
-
validates_presence_of :name, :identifier
validates_uniqueness_of :identifier, :if => Proc.new {|p| p.identifier_changed?}
validates_length_of :name, :maximum => 255
@@ -80,9 +78,9 @@ class Project < ActiveRecord::Base
validates_exclusion_of :identifier, :in => %w( new )
validate :validate_parent
- after_save :update_inherited_members, :if => Proc.new {|project| project.inherit_members_changed?}
- after_save :remove_inherited_member_roles, :add_inherited_member_roles, :if => Proc.new {|project| project.parent_id_changed?}
- after_update :update_versions_from_hierarchy_change, :if => Proc.new {|project| project.parent_id_changed?}
+ after_save :update_inherited_members, :if => Proc.new {|project| project.saved_change_to_inherit_members?}
+ after_save :remove_inherited_member_roles, :add_inherited_member_roles, :if => Proc.new {|project| project.saved_change_to_parent_id?}
+ after_update :update_versions_from_hierarchy_change, :if => Proc.new {|project| project.saved_change_to_parent_id?}
before_destroy :delete_all_members
scope :has_module, lambda {|mod|
@@ -257,6 +255,15 @@ class Project < ActiveRecord::Base
scope
end
+ # Creates or updates project time entry activities
+ def update_or_create_time_entry_activities(activities)
+ transaction do
+ activities.each do |id, activity|
+ update_or_create_time_entry_activity(id, activity)
+ end
+ end
+ end
+
# Will create a new Project specific Activity or update an existing one
#
# This will raise a ActiveRecord::Rollback if the TimeEntryActivity
@@ -776,6 +783,10 @@ class Project < ActiveRecord::Base
:if => lambda {|project, user| project.parent.nil? || project.parent.visible?(user)}
def safe_attributes=(attrs, user=User.current)
+ if attrs.respond_to?(:to_unsafe_hash)
+ attrs = attrs.to_unsafe_hash
+ end
+
return unless attrs.is_a?(Hash)
attrs = attrs.deep_dup
@@ -872,10 +883,10 @@ class Project < ActiveRecord::Base
def update_inherited_members
if parent
- if inherit_members? && !inherit_members_was
+ if inherit_members? && !inherit_members_before_last_save
remove_inherited_member_roles
add_inherited_member_roles
- elsif !inherit_members? && inherit_members_was
+ elsif !inherit_members? && inherit_members_before_last_save
remove_inherited_member_roles
end
end
diff --git a/app/models/query.rb b/app/models/query.rb
index 02e808eca..fc6f97a6c 100644
--- a/app/models/query.rb
+++ b/app/models/query.rb
@@ -212,8 +212,6 @@ class Query < ActiveRecord::Base
serialize :sort_criteria, Array
serialize :options, Hash
- attr_protected :project_id, :user_id
-
validates_presence_of :name
validates_length_of :name, :maximum => 255
validates :visibility, :inclusion => { :in => [VISIBILITY_PUBLIC, VISIBILITY_ROLES, VISIBILITY_PRIVATE] }
@@ -223,7 +221,7 @@ class Query < ActiveRecord::Base
end
after_save do |query|
- if query.visibility_changed? && query.visibility != VISIBILITY_ROLES
+ if query.saved_change_to_visibility? && query.visibility != VISIBILITY_ROLES
query.roles.clear
end
end
@@ -623,7 +621,7 @@ class Query < ActiveRecord::Base
# Add multiple filters using +add_filter+
def add_filters(fields, operators, values)
- if fields.is_a?(Array) && operators.is_a?(Hash) && (values.nil? || values.is_a?(Hash))
+ if fields.present? && operators.present?
fields.each do |field|
add_filter(field, operators[field], values && values[field])
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index fd3a9fbf6..b3886d536 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -48,7 +48,6 @@ class Repository < ActiveRecord::Base
# Checks if the SCM is enabled when creating a repository
validate :repo_create_validation, :on => :create
validate :validate_repository_path
- attr_protected :id
safe_attributes 'identifier',
'login',
diff --git a/app/models/repository/bazaar.rb b/app/models/repository/bazaar.rb
index 9cc84daa0..431565dfb 100644
--- a/app/models/repository/bazaar.rb
+++ b/app/models/repository/bazaar.rb
@@ -18,7 +18,6 @@
require 'redmine/scm/adapters/bazaar_adapter'
class Repository::Bazaar < Repository
- attr_protected :root_url
validates_presence_of :url, :log_encoding
def self.human_attribute_name(attribute_key_name, *args)
diff --git a/app/models/repository/filesystem.rb b/app/models/repository/filesystem.rb
index 0a612ae8e..0b370f39e 100644
--- a/app/models/repository/filesystem.rb
+++ b/app/models/repository/filesystem.rb
@@ -21,7 +21,6 @@
require 'redmine/scm/adapters/filesystem_adapter'
class Repository::Filesystem < Repository
- attr_protected :root_url
validates_presence_of :url
def self.human_attribute_name(attribute_key_name, *args)
diff --git a/app/models/repository/git.rb b/app/models/repository/git.rb
index 893dc533d..4cb16e524 100644
--- a/app/models/repository/git.rb
+++ b/app/models/repository/git.rb
@@ -19,7 +19,6 @@
require 'redmine/scm/adapters/git_adapter'
class Repository::Git < Repository
- attr_protected :root_url
validates_presence_of :url
safe_attributes 'report_last_commit'
diff --git a/app/models/repository/mercurial.rb b/app/models/repository/mercurial.rb
index b9a767fec..922893a6a 100644
--- a/app/models/repository/mercurial.rb
+++ b/app/models/repository/mercurial.rb
@@ -23,7 +23,6 @@ class Repository::Mercurial < Repository
lambda {order("#{Changeset.table_name}.id DESC")},
:foreign_key => 'repository_id'
- attr_protected :root_url
validates_presence_of :url
# number of changesets to fetch at once
diff --git a/app/models/repository/subversion.rb b/app/models/repository/subversion.rb
index 70d497771..bc4e9f2e8 100644
--- a/app/models/repository/subversion.rb
+++ b/app/models/repository/subversion.rb
@@ -18,7 +18,6 @@
require 'redmine/scm/adapters/subversion_adapter'
class Repository::Subversion < Repository
- attr_protected :root_url
validates_presence_of :url
validates_format_of :url, :with => %r{\A(http|https|svn(\+[^\s:\/\\]+)?|file):\/\/.+}i
diff --git a/app/models/role.rb b/app/models/role.rb
index 8bd2e7258..cdd8fd394 100644
--- a/app/models/role.rb
+++ b/app/models/role.rb
@@ -77,7 +77,6 @@ class Role < ActiveRecord::Base
serialize :permissions, ::Role::PermissionsAttributeCoder
store :settings, :accessors => [:permissions_all_trackers, :permissions_tracker_ids]
- attr_protected :builtin
validates_presence_of :name
validates_uniqueness_of :name
diff --git a/app/models/setting.rb b/app/models/setting.rb
index 6e702505e..b73aae4f2 100644
--- a/app/models/setting.rb
+++ b/app/models/setting.rb
@@ -82,7 +82,6 @@ class Setting < ActiveRecord::Base
validates_numericality_of :value, :only_integer => true, :if => Proc.new { |setting|
(s = available_settings[setting.name]) && s['format'] == 'int'
}
- attr_protected :id
# Hash used to cache setting values
@cached_settings = {}
diff --git a/app/models/time_entry.rb b/app/models/time_entry.rb
index 80d14ad15..d64c311fa 100644
--- a/app/models/time_entry.rb
+++ b/app/models/time_entry.rb
@@ -24,8 +24,6 @@ class TimeEntry < ActiveRecord::Base
belongs_to :user
belongs_to :activity, :class_name => 'TimeEntryActivity'
- attr_protected :user_id, :tyear, :tmonth, :tweek
-
acts_as_customizable
acts_as_event :title => Proc.new { |o|
related = o.issue if o.issue && o.issue.visible?
diff --git a/app/models/token.rb b/app/models/token.rb
index ee43865c1..5990056f5 100644
--- a/app/models/token.rb
+++ b/app/models/token.rb
@@ -18,7 +18,6 @@
class Token < ActiveRecord::Base
belongs_to :user
validates_uniqueness_of :value
- attr_protected :id
before_create :delete_previous_tokens, :generate_new_token
diff --git a/app/models/tracker.rb b/app/models/tracker.rb
index 59263214f..9524a620c 100644
--- a/app/models/tracker.rb
+++ b/app/models/tracker.rb
@@ -37,8 +37,6 @@ class Tracker < ActiveRecord::Base
has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => "#{table_name_prefix}custom_fields_trackers#{table_name_suffix}", :association_foreign_key => 'custom_field_id'
acts_as_positioned
- attr_protected :fields_bits
-
validates_presence_of :default_status
validates_presence_of :name
validates_uniqueness_of :name
diff --git a/app/models/user.rb b/app/models/user.rb
index 62a0289f0..7cdf78678 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -99,9 +99,6 @@ class User < Principal
attr_accessor :last_before_login_on
attr_accessor :remote_ip
- # Prevents unauthorized assignments
- attr_protected :password, :password_confirmation, :hashed_password
-
LOGIN_LENGTH_LIMIT = 60
MAIL_LENGTH_LIMIT = 60
@@ -771,9 +768,9 @@ class User < Principal
case mail_notification
when 'selected', 'only_my_events'
# user receives notifications for created/assigned issues on unselected projects
- object.author == self || is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.assigned_to_was)
+ object.author == self || is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.previous_assignee)
when 'only_assigned'
- is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.assigned_to_was)
+ is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.previous_assignee)
when 'only_owner'
object.author == self
end
@@ -845,7 +842,7 @@ class User < Principal
# This helps to keep the account secure in case the associated email account
# was compromised.
def destroy_tokens
- if hashed_password_changed? || (status_changed? && !active?)
+ if saved_change_to_hashed_password? || (saved_change_to_status? && !active?)
tokens = ['recovery', 'autologin', 'session']
Token.where(:user_id => id, :action => tokens).delete_all
end
@@ -900,16 +897,16 @@ class User < Principal
}
deliver = false
- if (admin? && id_changed? && active?) || # newly created admin
- (admin? && admin_changed? && active?) || # regular user became admin
- (admin? && status_changed? && active?) # locked admin became active again
+ if (admin? && saved_change_to_id? && active?) || # newly created admin
+ (admin? && saved_change_to_admin? && active?) || # regular user became admin
+ (admin? && saved_change_to_status? && active?) # locked admin became active again
deliver = true
options[:message] = :mail_body_security_notification_add
elsif (admin? && destroyed? && active?) || # active admin user was deleted
- (!admin? && admin_changed? && active?) || # admin is no longer admin
- (admin? && status_changed? && !active?) # admin was locked
+ (!admin? && saved_change_to_admin? && active?) || # admin is no longer admin
+ (admin? && saved_change_to_status? && !active?) # admin was locked
deliver = true
options[:message] = :mail_body_security_notification_remove
diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb
index c6b7fc2ac..1bf60c7f6 100644
--- a/app/models/user_preference.rb
+++ b/app/models/user_preference.rb
@@ -21,8 +21,6 @@ class UserPreference < ActiveRecord::Base
belongs_to :user
serialize :others
- attr_protected :others, :user_id
-
before_save :set_others_hash, :clear_unused_block_settings
safe_attributes 'hide_mail',
diff --git a/app/models/version.rb b/app/models/version.rb
index b48938913..4c559dcad 100644
--- a/app/models/version.rb
+++ b/app/models/version.rb
@@ -39,7 +39,6 @@ class Version < ActiveRecord::Base
validates :effective_date, :date => true
validates_inclusion_of :status, :in => VERSION_STATUSES
validates_inclusion_of :sharing, :in => VERSION_SHARINGS
- attr_protected :id
scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
scope :like, lambda {|arg|
@@ -302,10 +301,10 @@ class Version < ActiveRecord::Base
# Update the issue's fixed versions. Used if a version's sharing changes.
def update_issues_from_sharing_change
- if sharing_changed?
- if VERSION_SHARINGS.index(sharing_was).nil? ||
+ if saved_change_to_sharing?
+ if VERSION_SHARINGS.index(sharing_before_last_save).nil? ||
VERSION_SHARINGS.index(sharing).nil? ||
- VERSION_SHARINGS.index(sharing_was) > VERSION_SHARINGS.index(sharing)
+ VERSION_SHARINGS.index(sharing_before_last_save) > VERSION_SHARINGS.index(sharing)
Issue.update_versions_from_sharing_change self
end
end
diff --git a/app/models/watcher.rb b/app/models/watcher.rb
index 6198ceffc..30118845b 100644
--- a/app/models/watcher.rb
+++ b/app/models/watcher.rb
@@ -22,7 +22,6 @@ class Watcher < ActiveRecord::Base
validates_presence_of :user
validates_uniqueness_of :user_id, :scope => [:watchable_type, :watchable_id]
validate :validate_user
- attr_protected :id
# Returns true if at least one object among objects is watched by user
def self.any_watched?(objects, user)
diff --git a/app/models/wiki.rb b/app/models/wiki.rb
index 9ed9554cb..683fa24f3 100644
--- a/app/models/wiki.rb
+++ b/app/models/wiki.rb
@@ -26,7 +26,6 @@ class Wiki < ActiveRecord::Base
validates_presence_of :start_page
validates_format_of :start_page, :with => /\A[^,\.\/\?\;\|\:]*\z/
validates_length_of :start_page, maximum: 255
- attr_protected :id
before_destroy :delete_redirects
diff --git a/app/models/wiki_content.rb b/app/models/wiki_content.rb
index 3d992f8f7..0de717cd4 100644
--- a/app/models/wiki_content.rb
+++ b/app/models/wiki_content.rb
@@ -23,7 +23,6 @@ class WikiContent < ActiveRecord::Base
belongs_to :author, :class_name => 'User'
validates_presence_of :text
validates_length_of :comments, :maximum => 1024, :allow_nil => true
- attr_protected :id
acts_as_versioned
@@ -60,7 +59,6 @@ class WikiContent < ActiveRecord::Base
class Version
belongs_to :page, :class_name => '::WikiPage'
belongs_to :author, :class_name => '::User'
- attr_protected :data
acts_as_event :title => Proc.new {|o| "#{l(:label_wiki_edit)}: #{o.page.title} (##{o.version})"},
:description => :comments,
@@ -161,11 +159,11 @@ class WikiContent < ActiveRecord::Base
def send_notification
# new_record? returns false in after_save callbacks
- if id_changed?
+ if saved_change_to_id?
if Setting.notified_events.include?('wiki_content_added')
Mailer.wiki_content_added(self).deliver
end
- elsif text_changed?
+ elsif saved_change_to_text?
if Setting.notified_events.include?('wiki_content_updated')
Mailer.wiki_content_updated(self).deliver
end
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index d7b09f357..6e4cf0c03 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -47,7 +47,6 @@ class WikiPage < ActiveRecord::Base
validates_uniqueness_of :title, :scope => :wiki_id, :case_sensitive => false
validates_length_of :title, maximum: 255
validates_associated :content
- attr_protected :id
validate :validate_parent_title
before_destroy :delete_redirects
@@ -80,6 +79,10 @@ class WikiPage < ActiveRecord::Base
end
def safe_attributes=(attrs, user=User.current)
+ if attrs.respond_to?(:to_unsafe_hash)
+ attrs = attrs.to_unsafe_hash
+ end
+
return unless attrs.is_a?(Hash)
attrs = attrs.deep_dup
@@ -122,7 +125,7 @@ class WikiPage < ActiveRecord::Base
# Moves child pages if page was moved
def handle_children_move
- if !new_record? && wiki_id_changed?
+ if !new_record? && saved_change_to_wiki_id?
children.each do |child|
child.wiki_id = wiki_id
child.redirect_existing_links = redirect_existing_links
diff --git a/app/models/wiki_redirect.rb b/app/models/wiki_redirect.rb
index eb4de869a..79e96abee 100644
--- a/app/models/wiki_redirect.rb
+++ b/app/models/wiki_redirect.rb
@@ -20,7 +20,6 @@ class WikiRedirect < ActiveRecord::Base
validates_presence_of :wiki_id, :title, :redirects_to
validates_length_of :title, :redirects_to, :maximum => 255
- attr_protected :id
before_save :set_redirects_to_wiki_id
diff --git a/app/models/workflow_rule.rb b/app/models/workflow_rule.rb
index 8872d84c6..c4cbf1508 100644
--- a/app/models/workflow_rule.rb
+++ b/app/models/workflow_rule.rb
@@ -24,7 +24,6 @@ class WorkflowRule < ActiveRecord::Base
belongs_to :new_status, :class_name => 'IssueStatus'
validates_presence_of :role, :tracker
- attr_protected :id
# Copies workflows from source to targets
def self.copy(source_tracker, source_role, target_trackers, target_roles)