Project

General

Profile

« Previous | Next » 

Revision 16859

Merged rails-5.1 branch (#23630).

View differences:

trunk/Gemfile
4 4
  abort "Redmine requires Bundler 1.5.0 or higher (you're using #{Bundler::VERSION}).\nPlease update with 'gem update bundler'."
5 5
end
6 6

  
7
gem "rails", "4.2.8"
8
gem "jquery-rails", "~> 3.1.4"
7
gem "rails", "5.1.2"
9 8
gem "coderay", "~> 1.1.1"
10 9
gem "request_store", "1.0.5"
11 10
gem "mime-types", "~> 3.0"
12
gem "protected_attributes"
13 11
gem "actionpack-xml_parser"
14
gem "roadie-rails", "~> 1.1.1"
12
gem "roadie-rails"
15 13
gem "roadie", "~> 3.2.1"
16 14
gem "mimemagic"
17 15

  
18
gem "nokogiri", (RUBY_VERSION >= "2.1" ? "~> 1.7.2" : "~> 1.6.8")
16
gem "nokogiri", "~> 1.7.2"
19 17
gem "i18n", "~> 0.7.0"
20 18

  
21 19
# Request at least rails-html-sanitizer 1.0.3 because of security advisories
......
85 83
end
86 84

  
87 85
group :test do
88
  gem "minitest"
89 86
  gem "rails-dom-testing"
90 87
  gem "mocha"
91 88
  gem "simplecov", "~> 0.14.1", :require => false
92
  # TODO: remove this after upgrading to Rails 5
93
  gem "test_after_commit", "~> 0.4.2"
94 89
  # For running UI tests
95 90
  gem "capybara"
96 91
  gem "selenium-webdriver", "~> 2.53.4"
trunk/app/controllers/imports_controller.rb
109 109
  end
110 110

  
111 111
  def update_from_params
112
    if params[:import_settings].is_a?(Hash)
112
    if params[:import_settings].present?
113 113
      @import.settings ||= {}
114
      @import.settings.merge!(params[:import_settings])
114
      @import.settings.merge!(params[:import_settings].to_unsafe_hash)
115 115
      @import.save!
116 116
    end
117 117
  end
trunk/app/controllers/my_controller.rb
138 138
    block_settings = params[:settings] || {}
139 139

  
140 140
    block_settings.each do |block, settings|
141
      @user.pref.update_block_settings(block, settings)
141
      @user.pref.update_block_settings(block, settings.to_unsafe_hash)
142 142
    end
143 143
    @user.pref.save
144 144
    @updated_blocks = block_settings.keys
trunk/app/controllers/project_enumerations_controller.rb
20 20
  before_action :authorize
21 21

  
22 22
  def update
23
    if params[:enumerations]
24
      saved = Project.transaction do
25
        params[:enumerations].each do |id, activity|
26
          @project.update_or_create_time_entry_activity(id, activity)
27
        end
28
      end
29
      if saved
30
        flash[:notice] = l(:notice_successful_update)
31
      end
23
    if @project.update_or_create_time_entry_activities(update_params)
24
      flash[:notice] = l(:notice_successful_update)
32 25
    end
33 26

  
34 27
    redirect_to settings_project_path(@project, :tab => 'activities')
......
41 34
    flash[:notice] = l(:notice_successful_update)
42 35
    redirect_to settings_project_path(@project, :tab => 'activities')
43 36
  end
37

  
38
  private
39

  
40
  def update_params
41
    params.
42
      permit(:enumerations => [:parent_id, :active, {:custom_field_values => {}}]).
43
      require(:enumerations)
44
  end
44 45
end
trunk/app/controllers/search_controller.rb
68 68
    fetcher = Redmine::Search::Fetcher.new(
69 69
      @question, User.current, @scope, projects_to_search,
70 70
      :all_words => @all_words, :titles_only => @titles_only, :attachments => @search_attachments, :open_issues => @open_issues,
71
      :cache => params[:page].present?, :params => params
71
      :cache => params[:page].present?, :params => params.to_unsafe_hash
72 72
    )
73 73

  
74 74
    if fetcher.tokens.present?
trunk/app/controllers/settings_controller.rb
34 34
  def edit
35 35
    @notifiables = Redmine::Notifiable.all
36 36
    if request.post?
37
      errors = Setting.set_all_from_params(params[:settings])
37
      errors = Setting.set_all_from_params(params[:settings].to_unsafe_hash)
38 38
      if errors.blank?
39 39
        flash[:notice] = l(:notice_successful_update)
40 40
        redirect_to settings_path(:tab => params[:tab])
trunk/app/controllers/users_controller.rb
101 101
        format.html {
102 102
          flash[:notice] = l(:notice_user_successful_create, :id => view_context.link_to(@user.login, user_path(@user)))
103 103
          if params[:continue]
104
            attrs = params[:user].slice(:generate_password)
104
            attrs = {:generate_password => @user.generate_password }
105 105
            redirect_to new_user_path(:user => attrs)
106 106
          else
107 107
            redirect_to edit_user_path(@user)
trunk/app/helpers/application_helper.rb
1440 1440

  
1441 1441
  # Returns the javascript tags that are included in the html layout head
1442 1442
  def javascript_heads
1443
    tags = javascript_include_tag('jquery-1.11.1-ui-1.11.0-ujs-3.1.4', 'application', 'responsive')
1443
    tags = javascript_include_tag('jquery-1.11.1-ui-1.11.0-ujs-5.1.2', 'application', 'responsive')
1444 1444
    unless User.current.pref.warn_on_leaving_unsaved == '0'
1445 1445
      tags << "\n".html_safe + javascript_tag("$(window).load(function(){ warnLeavingUnsaved('#{escape_javascript l(:text_warn_on_leaving_unsaved)}'); });")
1446 1446
    end
trunk/app/models/attachment.rb
28 28
  validates_length_of :disk_filename, :maximum => 255
29 29
  validates_length_of :description, :maximum => 255
30 30
  validate :validate_max_file_size, :validate_file_extension
31
  attr_protected :id
32 31

  
33 32
  acts_as_event :title => :filename,
34 33
                :url => Proc.new {|o| {:controller => 'attachments', :action => 'show', :id => o.id, :filename => o.filename}}
trunk/app/models/auth_source.rb
30 30
  validates_presence_of :name
31 31
  validates_uniqueness_of :name
32 32
  validates_length_of :name, :maximum => 60
33
  attr_protected :id
34 33

  
35 34
  safe_attributes 'name',
36 35
    'host',
trunk/app/models/board.rb
28 28
  validates_length_of :name, :maximum => 30
29 29
  validates_length_of :description, :maximum => 255
30 30
  validate :validate_board
31
  attr_protected :id
32 31

  
33 32
  scope :visible, lambda {|*args|
34 33
    joins(:project).
trunk/app/models/change.rb
21 21
  validates_presence_of :changeset_id, :action, :path
22 22
  before_save :init_path
23 23
  before_validation :replace_invalid_utf8_of_path
24
  attr_protected :id
25 24

  
26 25
  def replace_invalid_utf8_of_path
27 26
    self.path      = Redmine::CodesetUtil.replace_invalid_utf8(self.path)
trunk/app/models/changeset.rb
46 46
  validates_presence_of :repository_id, :revision, :committed_on, :commit_date
47 47
  validates_uniqueness_of :revision, :scope => :repository_id
48 48
  validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true
49
  attr_protected :id
50 49

  
51 50
  scope :visible, lambda {|*args|
52 51
    joins(:repository => :project).
trunk/app/models/comment.rb
21 21
  belongs_to :author, :class_name => 'User'
22 22

  
23 23
  validates_presence_of :commented, :author, :comments
24
  attr_protected :id
25 24

  
26 25
  after_create :send_notification
27 26

  
trunk/app/models/custom_field.rb
35 35
  validates_length_of :regexp, maximum: 255
36 36
  validates_inclusion_of :field_format, :in => Proc.new { Redmine::FieldFormat.available_formats }
37 37
  validate :validate_custom_field
38
  attr_protected :id
39 38

  
40 39
  before_validation :set_searchable
41 40
  before_save do |field|
......
43 42
  end
44 43
  after_save :handle_multiplicity_change
45 44
  after_save do |field|
46
    if field.visible_changed? && field.visible
45
    if field.saved_change_to_visible? && field.visible
47 46
      field.roles.clear
48 47
    end
49 48
  end
......
316 315
  # Removes multiple values for the custom field after setting the multiple attribute to false
317 316
  # We kepp the value with the highest id for each customized object
318 317
  def handle_multiplicity_change
319
    if !new_record? && multiple_was && !multiple
318
    if !new_record? && multiple_before_last_save && !multiple
320 319
      ids = custom_values.
321 320
        where("EXISTS(SELECT 1 FROM #{CustomValue.table_name} cve WHERE cve.custom_field_id = #{CustomValue.table_name}.custom_field_id" +
322 321
          " AND cve.customized_type = #{CustomValue.table_name}.customized_type AND cve.customized_id = #{CustomValue.table_name}.customized_id" +
trunk/app/models/custom_value.rb
18 18
class CustomValue < ActiveRecord::Base
19 19
  belongs_to :custom_field
20 20
  belongs_to :customized, :polymorphic => true
21
  attr_protected :id
22 21

  
23 22
  after_save :custom_field_after_save_custom_value
24 23

  
trunk/app/models/document.rb
31 31

  
32 32
  validates_presence_of :project, :title, :category
33 33
  validates_length_of :title, :maximum => 255
34
  attr_protected :id
35 34

  
36 35
  after_create :send_notification
37 36

  
trunk/app/models/email_address.rb
19 19
  include Redmine::SafeAttributes
20 20

  
21 21
  belongs_to :user
22
  attr_protected :id
23 22

  
24 23
  after_create :deliver_security_notification_create
25 24
  after_update :destroy_tokens, :deliver_security_notification_update
......
63 62

  
64 63
  # send a security notification to user that an email has been changed (notified/not notified)
65 64
  def deliver_security_notification_update
66
    if address_changed?
67
      recipients = [user, address_was]
65
    if saved_change_to_address?
66
      recipients = [user, address_before_last_save]
68 67
      options = {
69 68
        message: :mail_body_security_notification_change_to,
70 69
        field: :field_mail,
71 70
        value: address
72 71
      }
73
    elsif notify_changed?
72
    elsif saved_change_to_notify?
74 73
      recipients = [user, address]
75 74
      options = {
76
        message: notify_was ? :mail_body_security_notification_notify_disabled : :mail_body_security_notification_notify_enabled,
75
        message: notify_before_last_save ? :mail_body_security_notification_notify_disabled : :mail_body_security_notification_notify_enabled,
77 76
        value: address
78 77
      }
79 78
    end
......
103 102
  # This helps to keep the account secure in case the associated email account
104 103
  # was compromised.
105 104
  def destroy_tokens
106
    if address_changed? || destroyed?
105
    if saved_change_to_address? || destroyed?
107 106
      tokens = ['recovery']
108 107
      Token.where(:user_id => user_id, :action => tokens).delete_all
109 108
    end
trunk/app/models/enabled_module.rb
21 21

  
22 22
  validates_presence_of :name
23 23
  validates_uniqueness_of :name, :scope => :project_id
24
  attr_protected :id
25 24

  
26 25
  after_create :module_enabled
27 26

  
trunk/app/models/enumeration.rb
29 29
  before_destroy :check_integrity
30 30
  before_save    :check_default
31 31

  
32
  attr_protected :type
33

  
34 32
  validates_presence_of :name
35 33
  validates_uniqueness_of :name, :scope => [:type, :project_id]
36 34
  validates_length_of :name, :maximum => 30
......
148 146
  # position as the overridden enumeration
149 147
  def update_position
150 148
    super
151
    if position_changed?
149
    if saved_change_to_position?
152 150
      self.class.where.not(:parent_id => nil).update_all(
153 151
        "position = coalesce((
154 152
          select position
trunk/app/models/group.rb
28 28
  validates_presence_of :lastname
29 29
  validates_uniqueness_of :lastname, :case_sensitive => false
30 30
  validates_length_of :lastname, :maximum => 255
31
  attr_protected :id
32 31

  
33 32
  self.valid_statuses = [STATUS_ACTIVE]
34 33

  
trunk/app/models/issue.rb
69 69
  validates :start_date, :date => true
70 70
  validates :due_date, :date => true
71 71
  validate :validate_issue, :validate_required_fields, :validate_permissions
72
  attr_protected :id
73 72

  
74 73
  scope :visible, lambda {|*args|
75 74
    joins(:project).
......
108 107
  before_validation :default_assign, on: :create
109 108
  before_validation :clear_disabled_fields
110 109
  before_save :close_duplicates, :update_done_ratio_from_issue_status,
111
              :force_updated_on_change, :update_closed_on, :set_assigned_to_was
112
  after_save {|issue| issue.send :after_project_change if !issue.id_changed? && issue.project_id_changed?}
110
              :force_updated_on_change, :update_closed_on
111
  after_save {|issue| issue.send :after_project_change if !issue.saved_change_to_id? && issue.saved_change_to_project_id?}
113 112
  after_save :reschedule_following_issues, :update_nested_set_attributes,
114 113
             :update_parent_attributes, :delete_selected_attachments, :create_journal
115 114
  # Should be after_create but would be called before previous after_save callbacks
116 115
  after_save :after_create_from_copy
117 116
  after_destroy :update_parent_attributes
118 117
  after_create :send_notification
119
  # Keep it at the end of after_save callbacks
120
  after_save :clear_assigned_to_was
121 118

  
122 119
  # Returns a SQL conditions string used to find all issues visible by the specified user
123 120
  def self.visible_condition(user, options={})
......
208 205
    end
209 206
  end
210 207

  
211
  def create_or_update
208
  def create_or_update(*args)
212 209
    super
213 210
  ensure
214 211
    @status_was = nil
......
512 509
  # attr_accessible is too rough because we still want things like
513 510
  # Issue.new(:project => foo) to work
514 511
  def safe_attributes=(attrs, user=User.current)
512
    if attrs.respond_to?(:to_unsafe_hash)
513
      attrs = attrs.to_unsafe_hash
514
    end
515

  
515 516
    @attributes_set_by = user
516 517
    return unless attrs.is_a?(Hash)
517 518

  
......
586 587
      attrs['custom_fields'].select! {|c| editable_custom_field_ids.include?(c['id'].to_s)}
587 588
    end
588 589

  
589
    # mass-assignment security bypass
590
    assign_attributes attrs, :without_protection => true
590
    assign_attributes attrs
591 591
  end
592 592

  
593 593
  def disabled_core_fields
......
1007 1007
    statuses
1008 1008
  end
1009 1009

  
1010
  # Returns the previous assignee (user or group) if changed
1011
  def assigned_to_was
1012
    # assigned_to_id_was is reset before after_save callbacks
1013
    user_id = @previous_assigned_to_id || assigned_to_id_was
1014
    if user_id && user_id != assigned_to_id
1015
      @assigned_to_was ||= Principal.find_by_id(user_id)
1016
    end
1017
  end
1018

  
1019 1010
  # Returns the original tracker
1020 1011
  def tracker_was
1021
    Tracker.find_by_id(tracker_id_was)
1012
    Tracker.find_by_id(tracker_id_in_database)
1022 1013
  end
1023 1014

  
1015
  # Returns the previous assignee whenever we're before the save
1016
  # or in after_* callbacks
1017
  def previous_assignee
1018
    # This is how ActiveRecord::AttributeMethods::Dirty checks if we're in a after_* callback
1019
    if previous_assigned_to_id = mutation_tracker.equal?(mutations_from_database) ? assigned_to_id_in_database : assigned_to_id_before_last_save
1020
      Principal.find_by_id(previous_assigned_to_id)
1021
    end
1022
  end
1023

  
1024 1024
  # Returns the users that should be notified
1025 1025
  def notified_users
1026
    notified = []
1027 1026
    # Author and assignee are always notified unless they have been
1028 1027
    # locked or don't want to be notified
1029
    notified << author if author
1030
    if assigned_to
1031
      notified += (assigned_to.is_a?(Group) ? assigned_to.users : [assigned_to])
1032
    end
1033
    if assigned_to_was
1034
      notified += (assigned_to_was.is_a?(Group) ? assigned_to_was.users : [assigned_to_was])
1035
    end
1028
    notified = [author, assigned_to, previous_assignee].compact.uniq
1029
    notified = notified.map {|n| n.is_a?(Group) ? n.users : n}.flatten
1030
    notified.uniq!
1036 1031
    notified = notified.select {|u| u.active? && u.notify_about?(self)}
1037 1032

  
1038 1033
    notified += project.notified_users
......
1587 1582

  
1588 1583
    # Move subtasks that were in the same project
1589 1584
    children.each do |child|
1590
      next unless child.project_id == project_id_was
1585
      next unless child.project_id == project_id_before_last_save
1591 1586
      # Change project and keep project
1592 1587
      child.send :project=, project, true
1593 1588
      unless child.save
......
1644 1639
  end
1645 1640

  
1646 1641
  def update_nested_set_attributes
1647
    if parent_id_changed?
1642
    if saved_change_to_parent_id?
1648 1643
      update_nested_set_attributes_on_parent_change
1649 1644
    end
1650 1645
    remove_instance_variable(:@parent_issue) if instance_variable_defined?(:@parent_issue)
......
1652 1647

  
1653 1648
  # Updates the nested set for when an existing issue is moved
1654 1649
  def update_nested_set_attributes_on_parent_change
1655
    former_parent_id = parent_id_was
1650
    former_parent_id = parent_id_before_last_save
1656 1651
    # delete invalid relations of all descendants
1657 1652
    self_and_descendants.each do |issue|
1658 1653
      issue.relations.each do |relation|
......
1789 1784

  
1790 1785
  # Updates start/due dates of following issues
1791 1786
  def reschedule_following_issues
1792
    if start_date_changed? || due_date_changed?
1787
    if saved_change_to_start_date? || saved_change_to_due_date?
1793 1788
      relations_from.each do |relation|
1794 1789
        relation.set_issue_to_dates
1795 1790
      end
......
1848 1843
    end
1849 1844
  end
1850 1845

  
1851
  # Stores the previous assignee so we can still have access
1852
  # to it during after_save callbacks (assigned_to_id_was is reset)
1853
  def set_assigned_to_was
1854
    @previous_assigned_to_id = assigned_to_id_was
1855
  end
1856

  
1857
  # Clears the previous assignee at the end of after_save callbacks
1858
  def clear_assigned_to_was
1859
    @assigned_to_was = nil
1860
    @previous_assigned_to_id = nil
1861
  end
1862

  
1863 1846
  def clear_disabled_fields
1864 1847
    if tracker
1865 1848
      tracker.disabled_core_fields.each do |attribute|
trunk/app/models/issue_category.rb
24 24
  validates_presence_of :name
25 25
  validates_uniqueness_of :name, :scope => [:project_id]
26 26
  validates_length_of :name, :maximum => 60
27
  attr_protected :id
28 27

  
29 28
  safe_attributes 'name', 'assigned_to_id'
30 29

  
trunk/app/models/issue_custom_field.rb
16 16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 17

  
18 18
class IssueCustomField < CustomField
19
  has_and_belongs_to_many :projects, :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", :foreign_key => "custom_field_id"
20
  has_and_belongs_to_many :trackers, :join_table => "#{table_name_prefix}custom_fields_trackers#{table_name_suffix}", :foreign_key => "custom_field_id"
19
  has_and_belongs_to_many :projects, :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", :foreign_key => "custom_field_id", :autosave => true
20
  has_and_belongs_to_many :trackers, :join_table => "#{table_name_prefix}custom_fields_trackers#{table_name_suffix}", :foreign_key => "custom_field_id", :autosave => true
21 21
  has_many :issues, :through => :issue_custom_values
22 22

  
23 23
  safe_attributes 'project_ids',
trunk/app/models/issue_priority.rb
19 19
  has_many :issues, :foreign_key => 'priority_id'
20 20

  
21 21
  after_destroy {|priority| priority.class.compute_position_names}
22
  after_save {|priority| priority.class.compute_position_names if (priority.position_changed? && priority.position) || priority.active_changed?}
22
  after_save {|priority| priority.class.compute_position_names if (priority.saved_change_to_position? && priority.position) || priority.saved_change_to_active?}
23 23

  
24 24
  OptionName = :enumeration_issue_priorities
25 25

  
trunk/app/models/issue_relation.rb
72 72
  validates_uniqueness_of :issue_to_id, :scope => :issue_from_id
73 73
  validate :validate_issue_relation
74 74

  
75
  attr_protected :issue_from_id, :issue_to_id
76 75
  before_save :handle_issue_order
77 76
  after_create  :call_issues_relation_added_callback
78 77
  after_destroy :call_issues_relation_removed_callback
......
82 81
    'issue_to_id'
83 82

  
84 83
  def safe_attributes=(attrs, user=User.current)
84
    if attrs.respond_to?(:to_unsafe_hash)
85
      attrs = attrs.to_unsafe_hash
86
    end
87

  
85 88
    return unless attrs.is_a?(Hash)
86 89
    attrs = attrs.deep_dup
87 90

  
trunk/app/models/issue_status.rb
30 30
  validates_uniqueness_of :name
31 31
  validates_length_of :name, :maximum => 30
32 32
  validates_inclusion_of :default_done_ratio, :in => 0..100, :allow_nil => true
33
  attr_protected :id
34 33

  
35 34
  scope :sorted, lambda { order(:position) }
36 35
  scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
......
89 88

  
90 89
  # Updates issues closed_on attribute when an existing status is set as closed.
91 90
  def handle_is_closed_change
92
    if is_closed_changed? && is_closed == true
91
    if saved_change_to_is_closed? && is_closed == true
93 92
      # First we update issues that have a journal for when the current status was set,
94 93
      # a subselect is used to update all issues with a single query
95 94
      subquery = Journal.joins(:details).
trunk/app/models/journal.rb
26 26
  belongs_to :user
27 27
  has_many :details, :class_name => "JournalDetail", :dependent => :delete_all, :inverse_of => :journal
28 28
  attr_accessor :indice
29
  attr_protected :id
30 29

  
31 30
  acts_as_event :title => Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.id}#{status}: #{o.issue.subject}" },
32 31
                :description => :notes,
trunk/app/models/journal_detail.rb
17 17

  
18 18
class JournalDetail < ActiveRecord::Base
19 19
  belongs_to :journal
20
  attr_protected :id
21 20

  
22 21
  def custom_field
23 22
    if property == 'cf'
trunk/app/models/member.rb
25 25
  validates_presence_of :principal, :project
26 26
  validates_uniqueness_of :user_id, :scope => :project_id
27 27
  validate :validate_role
28
  attr_protected :id
29 28

  
30 29
  before_destroy :set_issue_category_nil, :remove_from_project_default_assigned_to
31 30

  
trunk/app/models/member_role.rb
26 26

  
27 27
  validates_presence_of :role
28 28
  validate :validate_role_member
29
  attr_protected :id
30 29

  
31 30
  def validate_role_member
32 31
    errors.add :role_id, :invalid if role && !role.member?
trunk/app/models/message.rb
22 22
  acts_as_tree :counter_cache => :replies_count, :order => "#{Message.table_name}.created_on ASC"
23 23
  acts_as_attachable
24 24
  belongs_to :last_reply, :class_name => 'Message'
25
  attr_protected :id
26 25

  
27 26
  acts_as_searchable :columns => ['subject', 'content'],
28 27
                     :preload => {:board => :project},
......
69 68
  end
70 69

  
71 70
  def update_messages_board
72
    if board_id_changed?
71
    if saved_change_to_board_id?
73 72
      Message.where(["id = ? OR parent_id = ?", root.id, root.id]).update_all({:board_id => board_id})
74
      Board.reset_counters!(board_id_was)
73
      Board.reset_counters!(board_id_before_last_save)
75 74
      Board.reset_counters!(board_id)
76 75
    end
77 76
  end
trunk/app/models/news.rb
24 24
  validates_presence_of :title, :description
25 25
  validates_length_of :title, :maximum => 60
26 26
  validates_length_of :summary, :maximum => 255
27
  attr_protected :id
28 27

  
29 28
  acts_as_attachable :edit_permission => :manage_news,
30 29
                     :delete_permission => :manage_news
trunk/app/models/project.rb
67 67
                :url => Proc.new {|o| {:controller => 'projects', :action => 'show', :id => o}},
68 68
                :author => nil
69 69

  
70
  attr_protected :status
71

  
72 70
  validates_presence_of :name, :identifier
73 71
  validates_uniqueness_of :identifier, :if => Proc.new {|p| p.identifier_changed?}
74 72
  validates_length_of :name, :maximum => 255
......
80 78
  validates_exclusion_of :identifier, :in => %w( new )
81 79
  validate :validate_parent
82 80

  
83
  after_save :update_inherited_members, :if => Proc.new {|project| project.inherit_members_changed?}
84
  after_save :remove_inherited_member_roles, :add_inherited_member_roles, :if => Proc.new {|project| project.parent_id_changed?}
85
  after_update :update_versions_from_hierarchy_change, :if => Proc.new {|project| project.parent_id_changed?}
81
  after_save :update_inherited_members, :if => Proc.new {|project| project.saved_change_to_inherit_members?}
82
  after_save :remove_inherited_member_roles, :add_inherited_member_roles, :if => Proc.new {|project| project.saved_change_to_parent_id?}
83
  after_update :update_versions_from_hierarchy_change, :if => Proc.new {|project| project.saved_change_to_parent_id?}
86 84
  before_destroy :delete_all_members
87 85

  
88 86
  scope :has_module, lambda {|mod|
......
257 255
    scope
258 256
  end
259 257

  
258
  # Creates or updates project time entry activities
259
  def update_or_create_time_entry_activities(activities)
260
    transaction do
261
      activities.each do |id, activity|
262
        update_or_create_time_entry_activity(id, activity)
263
      end
264
    end
265
  end
266

  
260 267
  # Will create a new Project specific Activity or update an existing one
261 268
  #
262 269
  # This will raise a ActiveRecord::Rollback if the TimeEntryActivity
......
776 783
    :if => lambda {|project, user| project.parent.nil? || project.parent.visible?(user)}
777 784

  
778 785
  def safe_attributes=(attrs, user=User.current)
786
    if attrs.respond_to?(:to_unsafe_hash)
787
      attrs = attrs.to_unsafe_hash
788
    end
789

  
779 790
    return unless attrs.is_a?(Hash)
780 791
    attrs = attrs.deep_dup
781 792

  
......
872 883

  
873 884
  def update_inherited_members
874 885
    if parent
875
      if inherit_members? && !inherit_members_was
886
      if inherit_members? && !inherit_members_before_last_save
876 887
        remove_inherited_member_roles
877 888
        add_inherited_member_roles
878
      elsif !inherit_members? && inherit_members_was
889
      elsif !inherit_members? && inherit_members_before_last_save
879 890
        remove_inherited_member_roles
880 891
      end
881 892
    end
trunk/app/models/query.rb
212 212
  serialize :sort_criteria, Array
213 213
  serialize :options, Hash
214 214

  
215
  attr_protected :project_id, :user_id
216

  
217 215
  validates_presence_of :name
218 216
  validates_length_of :name, :maximum => 255
219 217
  validates :visibility, :inclusion => { :in => [VISIBILITY_PUBLIC, VISIBILITY_ROLES, VISIBILITY_PRIVATE] }
......
223 221
  end
224 222

  
225 223
  after_save do |query|
226
    if query.visibility_changed? && query.visibility != VISIBILITY_ROLES
224
    if query.saved_change_to_visibility? && query.visibility != VISIBILITY_ROLES
227 225
      query.roles.clear
228 226
    end
229 227
  end
......
623 621

  
624 622
  # Add multiple filters using +add_filter+
625 623
  def add_filters(fields, operators, values)
626
    if fields.is_a?(Array) && operators.is_a?(Hash) && (values.nil? || values.is_a?(Hash))
624
    if fields.present? && operators.present?
627 625
      fields.each do |field|
628 626
        add_filter(field, operators[field], values && values[field])
629 627
      end
trunk/app/models/repository/bazaar.rb
18 18
require 'redmine/scm/adapters/bazaar_adapter'
19 19

  
20 20
class Repository::Bazaar < Repository
21
  attr_protected :root_url
22 21
  validates_presence_of :url, :log_encoding
23 22

  
24 23
  def self.human_attribute_name(attribute_key_name, *args)
trunk/app/models/repository/filesystem.rb
21 21
require 'redmine/scm/adapters/filesystem_adapter'
22 22

  
23 23
class Repository::Filesystem < Repository
24
  attr_protected :root_url
25 24
  validates_presence_of :url
26 25

  
27 26
  def self.human_attribute_name(attribute_key_name, *args)
trunk/app/models/repository/git.rb
19 19
require 'redmine/scm/adapters/git_adapter'
20 20

  
21 21
class Repository::Git < Repository
22
  attr_protected :root_url
23 22
  validates_presence_of :url
24 23

  
25 24
  safe_attributes 'report_last_commit'
trunk/app/models/repository/mercurial.rb
23 23
           lambda {order("#{Changeset.table_name}.id DESC")},
24 24
           :foreign_key => 'repository_id'
25 25

  
26
  attr_protected        :root_url
27 26
  validates_presence_of :url
28 27

  
29 28
  # number of changesets to fetch at once
trunk/app/models/repository/subversion.rb
18 18
require 'redmine/scm/adapters/subversion_adapter'
19 19

  
20 20
class Repository::Subversion < Repository
21
  attr_protected :root_url
22 21
  validates_presence_of :url
23 22
  validates_format_of :url, :with => %r{\A(http|https|svn(\+[^\s:\/\\]+)?|file):\/\/.+}i
24 23

  
trunk/app/models/repository.rb
48 48
  # Checks if the SCM is enabled when creating a repository
49 49
  validate :repo_create_validation, :on => :create
50 50
  validate :validate_repository_path
51
  attr_protected :id
52 51

  
53 52
  safe_attributes 'identifier',
54 53
    'login',
trunk/app/models/role.rb
77 77

  
78 78
  serialize :permissions, ::Role::PermissionsAttributeCoder
79 79
  store :settings, :accessors => [:permissions_all_trackers, :permissions_tracker_ids]
80
  attr_protected :builtin
81 80

  
82 81
  validates_presence_of :name
83 82
  validates_uniqueness_of :name
trunk/app/models/setting.rb
82 82
  validates_numericality_of :value, :only_integer => true, :if => Proc.new { |setting|
83 83
    (s = available_settings[setting.name]) && s['format'] == 'int'
84 84
  }
85
  attr_protected :id
86 85

  
87 86
  # Hash used to cache setting values
88 87
  @cached_settings = {}
trunk/app/models/time_entry.rb
24 24
  belongs_to :user
25 25
  belongs_to :activity, :class_name => 'TimeEntryActivity'
26 26

  
27
  attr_protected :user_id, :tyear, :tmonth, :tweek
28

  
29 27
  acts_as_customizable
30 28
  acts_as_event :title => Proc.new { |o|
31 29
                  related   = o.issue if o.issue && o.issue.visible?
trunk/app/models/token.rb
18 18
class Token < ActiveRecord::Base
19 19
  belongs_to :user
20 20
  validates_uniqueness_of :value
21
  attr_protected :id
22 21

  
23 22
  before_create :delete_previous_tokens, :generate_new_token
24 23

  
trunk/app/models/tracker.rb
37 37
  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'
38 38
  acts_as_positioned
39 39

  
40
  attr_protected :fields_bits
41

  
42 40
  validates_presence_of :default_status
43 41
  validates_presence_of :name
44 42
  validates_uniqueness_of :name
trunk/app/models/user.rb
99 99
  attr_accessor :last_before_login_on
100 100
  attr_accessor :remote_ip
101 101

  
102
  # Prevents unauthorized assignments
103
  attr_protected :password, :password_confirmation, :hashed_password
104

  
105 102
  LOGIN_LENGTH_LIMIT = 60
106 103
  MAIL_LENGTH_LIMIT = 60
107 104

  
......
771 768
        case mail_notification
772 769
        when 'selected', 'only_my_events'
773 770
          # user receives notifications for created/assigned issues on unselected projects
774
          object.author == self || is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.assigned_to_was)
771
          object.author == self || is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.previous_assignee)
775 772
        when 'only_assigned'
776
          is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.assigned_to_was)
773
          is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.previous_assignee)
777 774
        when 'only_owner'
778 775
          object.author == self
779 776
        end
......
845 842
  # This helps to keep the account secure in case the associated email account
846 843
  # was compromised.
847 844
  def destroy_tokens
848
    if hashed_password_changed? || (status_changed? && !active?)
845
    if saved_change_to_hashed_password? || (saved_change_to_status? && !active?)
849 846
      tokens = ['recovery', 'autologin', 'session']
850 847
      Token.where(:user_id => id, :action => tokens).delete_all
851 848
    end
......
900 897
    }
901 898

  
902 899
    deliver = false
903
    if (admin? && id_changed? && active?) ||    # newly created admin
904
       (admin? && admin_changed? && active?) || # regular user became admin
905
       (admin? && status_changed? && active?)   # locked admin became active again
900
    if (admin? && saved_change_to_id? && active?) ||    # newly created admin
901
       (admin? && saved_change_to_admin? && active?) || # regular user became admin
902
       (admin? && saved_change_to_status? && active?)   # locked admin became active again
906 903

  
907 904
       deliver = true
908 905
       options[:message] = :mail_body_security_notification_add
909 906

  
910 907
    elsif (admin? && destroyed? && active?) ||      # active admin user was deleted
911
          (!admin? && admin_changed? && active?) || # admin is no longer admin
912
          (admin? && status_changed? && !active?)   # admin was locked
908
          (!admin? && saved_change_to_admin? && active?) || # admin is no longer admin
909
          (admin? && saved_change_to_status? && !active?)   # admin was locked
913 910

  
914 911
          deliver = true
915 912
          options[:message] = :mail_body_security_notification_remove
trunk/app/models/user_preference.rb
21 21
  belongs_to :user
22 22
  serialize :others
23 23

  
24
  attr_protected :others, :user_id
25

  
26 24
  before_save :set_others_hash, :clear_unused_block_settings
27 25

  
28 26
  safe_attributes 'hide_mail',
trunk/app/models/version.rb
39 39
  validates :effective_date, :date => true
40 40
  validates_inclusion_of :status, :in => VERSION_STATUSES
41 41
  validates_inclusion_of :sharing, :in => VERSION_SHARINGS
42
  attr_protected :id
43 42

  
44 43
  scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
45 44
  scope :like, lambda {|arg|
......
302 301

  
303 302
  # Update the issue's fixed versions. Used if a version's sharing changes.
304 303
  def update_issues_from_sharing_change
305
    if sharing_changed?
306
      if VERSION_SHARINGS.index(sharing_was).nil? ||
304
    if saved_change_to_sharing?
305
      if VERSION_SHARINGS.index(sharing_before_last_save).nil? ||
307 306
          VERSION_SHARINGS.index(sharing).nil? ||
308
          VERSION_SHARINGS.index(sharing_was) > VERSION_SHARINGS.index(sharing)
307
          VERSION_SHARINGS.index(sharing_before_last_save) > VERSION_SHARINGS.index(sharing)
309 308
        Issue.update_versions_from_sharing_change self
310 309
      end
311 310
    end
trunk/app/models/watcher.rb
22 22
  validates_presence_of :user
23 23
  validates_uniqueness_of :user_id, :scope => [:watchable_type, :watchable_id]
24 24
  validate :validate_user
25
  attr_protected :id
26 25

  
27 26
  # Returns true if at least one object among objects is watched by user
28 27
  def self.any_watched?(objects, user)
trunk/app/models/wiki.rb
26 26
  validates_presence_of :start_page
27 27
  validates_format_of :start_page, :with => /\A[^,\.\/\?\;\|\:]*\z/
28 28
  validates_length_of :start_page, maximum: 255
29
  attr_protected :id
30 29

  
31 30
  before_destroy :delete_redirects
32 31

  
trunk/app/models/wiki_content.rb
23 23
  belongs_to :author, :class_name => 'User'
24 24
  validates_presence_of :text
25 25
  validates_length_of :comments, :maximum => 1024, :allow_nil => true
26
  attr_protected :id
27 26

  
28 27
  acts_as_versioned
29 28

  
......
60 59
  class Version
61 60
    belongs_to :page, :class_name => '::WikiPage'
62 61
    belongs_to :author, :class_name => '::User'
63
    attr_protected :data
64 62

  
65 63
    acts_as_event :title => Proc.new {|o| "#{l(:label_wiki_edit)}: #{o.page.title} (##{o.version})"},
66 64
                  :description => :comments,
......
161 159

  
162 160
  def send_notification
163 161
    # new_record? returns false in after_save callbacks
164
    if id_changed?
162
    if saved_change_to_id?
165 163
      if Setting.notified_events.include?('wiki_content_added')
166 164
        Mailer.wiki_content_added(self).deliver
167 165
      end
168
    elsif text_changed?
166
    elsif saved_change_to_text?
169 167
      if Setting.notified_events.include?('wiki_content_updated')
170 168
        Mailer.wiki_content_updated(self).deliver
171 169
      end
trunk/app/models/wiki_page.rb
47 47
  validates_uniqueness_of :title, :scope => :wiki_id, :case_sensitive => false
48 48
  validates_length_of :title, maximum: 255
49 49
  validates_associated :content
50
  attr_protected :id
51 50

  
52 51
  validate :validate_parent_title
53 52
  before_destroy :delete_redirects
......
80 79
  end
81 80

  
82 81
  def safe_attributes=(attrs, user=User.current)
82
    if attrs.respond_to?(:to_unsafe_hash)
83
      attrs = attrs.to_unsafe_hash
84
    end
85

  
83 86
    return unless attrs.is_a?(Hash)
84 87
    attrs = attrs.deep_dup
85 88

  
......
122 125

  
123 126
  # Moves child pages if page was moved
124 127
  def handle_children_move
125
    if !new_record? && wiki_id_changed?
128
    if !new_record? && saved_change_to_wiki_id?
126 129
      children.each do |child|
127 130
        child.wiki_id = wiki_id
128 131
        child.redirect_existing_links = redirect_existing_links
trunk/app/models/wiki_redirect.rb
20 20

  
21 21
  validates_presence_of :wiki_id, :title, :redirects_to
22 22
  validates_length_of :title, :redirects_to, :maximum => 255
23
  attr_protected :id
24 23

  
25 24
  before_save :set_redirects_to_wiki_id
26 25

  
trunk/app/models/workflow_rule.rb
24 24
  belongs_to :new_status, :class_name => 'IssueStatus'
25 25

  
26 26
  validates_presence_of :role, :tracker
27
  attr_protected :id
28 27

  
29 28
  # Copies workflows from source to targets
30 29
  def self.copy(source_tracker, source_role, target_trackers, target_roles)
trunk/app/views/welcome/robots.html.erb
1
User-agent: *
2
<% @projects.each do |p| -%>
3
Disallow: /projects/<%= p.to_param %>/repository
4
Disallow: /projects/<%= p.to_param %>/issues
5
Disallow: /projects/<%= p.to_param %>/activity
6
<% end -%>
7
Disallow: /issues/gantt
8
Disallow: /issues/calendar
9
Disallow: /activity
10
Disallow: /search
11 0

  
trunk/app/views/welcome/robots.text.erb
1
User-agent: *
2
<% @projects.each do |p| -%>
3
Disallow: /projects/<%= p.to_param %>/repository
4
Disallow: /projects/<%= p.to_param %>/issues
5
Disallow: /projects/<%= p.to_param %>/activity
6
<% end -%>
7
Disallow: /issues/gantt
8
Disallow: /issues/calendar
9
Disallow: /activity
10
Disallow: /search
0 11

  
trunk/config/application.rb
47 47
    # Do not include all helpers
48 48
    config.action_controller.include_all_helpers = false
49 49

  
50
    # Do not suppress errors in after_rollback and after_commit callbacks
51
    config.active_record.raise_in_transactional_callbacks = true
52

  
53
    # XML parameter parser removed from core in Rails 4.0
54
    # and extracted to actionpack-xml_parser gem
55
    config.middleware.insert_after ActionDispatch::ParamsParser, ActionDispatch::XmlParamsParser
56

  
57 50
    # Sets the Content-Length header on responses with fixed-length bodies
58 51
    config.middleware.insert_after Rack::Sendfile, Rack::ContentLength
59 52

  
trunk/config/initializers/10-patches.rb
27 27
    end
28 28
  end
29 29
  class Relation ; undef open ; end
30

  
31
  # Workaround for a Rails 5.1 regression that breaks queries with a condition
32
  # on a table that has a column with the same name as the table
33
  # (eg. comments.comments). It breaks has_many associations to these tables as well.
34
  # https://github.com/rails/rails/commit/c6a62dc327c54baec87306f5c381e13cacc00a19
35
  #
36
  # Examples (without the following workaround applied):
37
  #   Comment.where(:comments => {:id => 1})
38
  #   TypeError: can't cast Hash
39
  #
40
  #   News.first.comments.count
41
  #   TypeError: can't cast Hash
42
  class PredicateBuilder
43

  
44
    protected
45
    alias :create_binds_for_hash_without_comments_fix :create_binds_for_hash
46
    def create_binds_for_hash(attributes)
47
      if attributes["comments"].is_a?(Hash)
48
        return create_binds_for_hash_without_comments_fix attributes["comments"]
49
      else
50
        create_binds_for_hash_without_comments_fix attributes
51
      end
52
    end
53
  end  
30 54
end
31 55

  
32 56
module ActionView
......
201 225
        unless asset_id.blank?
202 226
          source += "?#{asset_id}"
203 227
        end
204
        asset_path(source, options)
228
        asset_path(source, options.merge(skip_pipeline: true))
205 229
      end
206 230
      alias :path_to_asset :asset_path_with_asset_id
207 231

  
......
218 242
            if File.exist? path
219 243
              exist = true
220 244
            else
221
              path = File.join(Rails.public_path, compute_asset_path("#{source}#{extname}", options))
245
              path = File.join(Rails.public_path, public_compute_asset_path("#{source}#{extname}", options))
222 246
              if File.exist? path
223 247
                exist = true
224 248
              end
trunk/config/initializers/20-mime_types.rb
1 1
# Add new mime types for use in respond_to blocks:
2

  
3
Mime::SET << Mime::CSV unless Mime::SET.include?(Mime::CSV)
4

  
trunk/config/routes.rb
242 242
  get 'projects/:id/repository/:repository_id/statistics', :to => 'repositories#stats'
243 243
  get 'projects/:id/repository/:repository_id/graph', :to => 'repositories#graph'
244 244

  
245
  get 'projects/:id/repository/:repository_id/changes(/*path)',
246
      :to => 'repositories#changes',
247
      :format => false
248

  
249 245
  get 'projects/:id/repository/:repository_id/revisions/:rev', :to => 'repositories#revision'
250 246
  get 'projects/:id/repository/:repository_id/revision', :to => 'repositories#revision'
251 247
  post   'projects/:id/repository/:repository_id/revisions/:rev/issues', :to => 'repositories#add_related_issue'
......
255 251
    get "projects/:id/repository/:repository_id/revisions/:rev/#{action}(/*path)",
256 252
        :controller => 'repositories',
257 253
        :action => action,
258
        :format => false,
259
        :constraints => {:rev => /[a-z0-9\.\-_]+/}
254
        :format => 'html',
255
        :constraints => {:rev => /[a-z0-9\.\-_]+/, :path => /.*/}
260 256
  end
261 257

  
262 258
  get 'projects/:id/repository/statistics', :to => 'repositories#stats'
263 259
  get 'projects/:id/repository/graph', :to => 'repositories#graph'
264 260

  
265
  get 'projects/:id/repository/changes(/*path)',
266
      :to => 'repositories#changes',
267
      :format => false
268

  
269 261
  get 'projects/:id/repository/revisions', :to => 'repositories#revisions'
270 262
  get 'projects/:id/repository/revisions/:rev', :to => 'repositories#revision'
271 263
  get 'projects/:id/repository/revision', :to => 'repositories#revision'
......
275 267
    get "projects/:id/repository/revisions/:rev/#{action}(/*path)",
276 268
        :controller => 'repositories',
277 269
        :action => action,
278
        :format => false,
279
        :constraints => {:rev => /[a-z0-9\.\-_]+/}
270
        :format => 'html',
271
        :constraints => {:rev => /[a-z0-9\.\-_]+/, :path => /.*/}
280 272
  end
281 273
  %w(browse entry raw changes annotate diff).each do |action|
282 274
    get "projects/:id/repository/:repository_id/#{action}(/*path)",
283 275
        :controller => 'repositories',
284 276
        :action => action,
285
        :format => false
277
        :format => 'html',
278
        :constraints => {:path => /.*/}
286 279
  end
287 280
  %w(browse entry raw changes annotate diff).each do |action|
288 281
    get "projects/:id/repository/#{action}(/*path)",
289 282
        :controller => 'repositories',
290 283
        :action => action,
291
        :format => false
284
        :format => 'html',
285
        :constraints => {:path => /.*/}
292 286
  end
293 287

  
294
  get 'projects/:id/repository/:repository_id/show/*path', :to => 'repositories#show', :format => false
295
  get 'projects/:id/repository/show/*path', :to => 'repositories#show', :format => false
288
  get 'projects/:id/repository/:repository_id/show/*path', :to => 'repositories#show', :format => 'html', :constraints => {:path => /.*/}
289
  get 'projects/:id/repository/show/*path', :to => 'repositories#show', :format => 'html', :constraints => {:path => /.*/}
296 290

  
297 291
  get 'projects/:id/repository/:repository_id', :to => 'repositories#show', :path => nil
298 292
  get 'projects/:id/repository', :to => 'repositories#show', :path => nil
299 293

  
300 294
  # additional routes for having the file name at the end of url
301
  get 'attachments/:id/:filename', :to => 'attachments#show', :id => /\d+/, :filename => /.*/, :as => 'named_attachment'
295
  get 'attachments/:id/:filename', :to => 'attachments#show', :id => /\d+/, :filename => /.*/, :as => 'named_attachment', :format => 'html'
302 296
  get 'attachments/download/:id/:filename', :to => 'attachments#download', :id => /\d+/, :filename => /.*/, :as => 'download_named_attachment'
303 297
  get 'attachments/download/:id', :to => 'attachments#download', :id => /\d+/
304 298
  get 'attachments/thumbnail/:id(/:size)', :to => 'attachments#thumbnail', :id => /\d+/, :size => /\d+/, :as => 'thumbnail'
......
376 370

  
377 371
  match 'uploads', :to => 'attachments#upload', :via => :post
378 372

  
379
  get 'robots.txt', :to => 'welcome#robots'
373
  get 'robots', :to => 'welcome#robots'
380 374

  
381 375
  Dir.glob File.expand_path("#{Redmine::Plugin.directory}/*") do |plugin_dir|
382 376
    file = File.join(plugin_dir, "config/routes.rb")
trunk/db/migrate/001_setup.rb
15 15
# along with this program; if not, write to the Free Software
16 16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 17

  
18
class Setup < ActiveRecord::Migration
18
class Setup < ActiveRecord::Migration[4.2]
19 19

  
20 20
  class User < ActiveRecord::Base
21
    attr_protected :id
22 21
  end
23 22

  
24 23
  # model removed
trunk/db/migrate/002_issue_move.rb
1
class IssueMove < ActiveRecord::Migration
1
class IssueMove < ActiveRecord::Migration[4.2]
2 2
  # model removed
3 3
  class Permission < ActiveRecord::Base; end
4 4

  
trunk/db/migrate/003_issue_add_note.rb
1
class IssueAddNote < ActiveRecord::Migration
1
class IssueAddNote < ActiveRecord::Migration[4.2]
2 2
  # model removed
3 3
  class Permission < ActiveRecord::Base; end
4 4

  
trunk/db/migrate/004_export_pdf.rb
1
class ExportPdf < ActiveRecord::Migration
1
class ExportPdf < ActiveRecord::Migration[4.2]
2 2
  # model removed
3 3
  class Permission < ActiveRecord::Base; end
4 4

  
trunk/db/migrate/005_issue_start_date.rb
1
class IssueStartDate < ActiveRecord::Migration
1
class IssueStartDate < ActiveRecord::Migration[4.2]
2 2
  def self.up
3 3
    add_column :issues, :start_date, :date
4 4
    add_column :issues, :done_ratio, :integer, :default => 0, :null => false
trunk/db/migrate/006_calendar_and_activity.rb
1
class CalendarAndActivity < ActiveRecord::Migration
1
class CalendarAndActivity < ActiveRecord::Migration[4.2]
2 2
  # model removed
3 3
  class Permission < ActiveRecord::Base; end
4 4

  
trunk/db/migrate/007_create_journals.rb
1
class CreateJournals < ActiveRecord::Migration
1
class CreateJournals < ActiveRecord::Migration[4.2]
2 2

  
3 3
  # model removed, but needed for data migration
4 4
  class IssueHistory < ActiveRecord::Base; belongs_to :issue; end
trunk/db/migrate/008_create_user_preferences.rb
1
class CreateUserPreferences < ActiveRecord::Migration
1
class CreateUserPreferences < ActiveRecord::Migration[4.2]
2 2
  def self.up
3 3
    create_table :user_preferences do |t|
4 4
      t.column "user_id", :integer, :default => 0, :null => false
trunk/db/migrate/009_add_hide_mail_pref.rb
1
class AddHideMailPref < ActiveRecord::Migration
1
class AddHideMailPref < ActiveRecord::Migration[4.2]
2 2
  def self.up
3 3
    add_column :user_preferences, :hide_mail, :boolean, :default => false
4 4
  end
trunk/db/migrate/010_create_comments.rb
1
class CreateComments < ActiveRecord::Migration
1
class CreateComments < ActiveRecord::Migration[4.2]
2 2
  def self.up
3 3
    create_table :comments do |t|
4 4
      t.column :commented_type, :string, :limit => 30, :default => "", :null => false
trunk/db/migrate/011_add_news_comments_count.rb
1
class AddNewsCommentsCount < ActiveRecord::Migration
1
class AddNewsCommentsCount < ActiveRecord::Migration[4.2]
2 2
  def self.up
3 3
    add_column :news, :comments_count, :integer, :default => 0, :null => false
4 4
  end
trunk/db/migrate/012_add_comments_permissions.rb
1
class AddCommentsPermissions < ActiveRecord::Migration
1
class AddCommentsPermissions < ActiveRecord::Migration[4.2]
2 2
  # model removed
3 3
  class Permission < ActiveRecord::Base; end
4 4

  
trunk/db/migrate/013_create_queries.rb
1
class CreateQueries < ActiveRecord::Migration
1
class CreateQueries < ActiveRecord::Migration[4.2]
2 2
  def self.up
3 3
    create_table :queries, :force => true do |t|
4 4
      t.column "project_id", :integer
trunk/db/migrate/014_add_queries_permissions.rb
1
class AddQueriesPermissions < ActiveRecord::Migration
1
class AddQueriesPermissions < ActiveRecord::Migration[4.2]
2 2
  # model removed
3 3
  class Permission < ActiveRecord::Base; end
4 4

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff