diff options
author | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2017-07-23 11:26:04 +0000 |
---|---|---|
committer | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2017-07-23 11:26:04 +0000 |
commit | d74f0bfd5c53962e332c2dd4d30dafaa1105b92b (patch) | |
tree | f3eaf66d67c3a87fb34340561bf188d364de623c /app/models | |
parent | 41bb302594b48152b87c92f196c915f499093bbf (diff) | |
download | redmine-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')
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) |