enumeration-sti-3.patch

Latest conversion of Enumerations to an STI class - Eric Davis, 2009-04-02 00:45

Download (42.8 KB)

View differences:

app/controllers/documents_controller.rb
54 54
  end
55 55
  
56 56
  def edit
57
    @categories = Enumeration.document_categories
57
    @categories = DocumentCategory.all
58 58
    if request.post? and @document.update_attributes(params[:document])
59 59
      flash[:notice] = l(:notice_successful_update)
60 60
      redirect_to :action => 'show', :id => @document
app/controllers/enumerations_controller.rb
31 31
  end
32 32

  
33 33
  def new
34
    @enumeration = Enumeration.new(:opt => params[:opt])
34
    begin
35
      @enumeration = params[:type].constantize.new
36
    rescue NameError
37
      @enumeration = Enumeration.new      
38
    end
35 39
  end
36 40

  
37 41
  def create
38 42
    @enumeration = Enumeration.new(params[:enumeration])
43
    @enumeration.type = params[:enumeration][:type]
39 44
    if @enumeration.save
40 45
      flash[:notice] = l(:notice_successful_create)
41
      redirect_to :action => 'list', :opt => @enumeration.opt
46
      redirect_to :action => 'list', :type => @enumeration.type
42 47
    else
43 48
      render :action => 'new'
44 49
    end
......
50 55

  
51 56
  def update
52 57
    @enumeration = Enumeration.find(params[:id])
58
    @enumeration.type = params[:enumeration][:type]
53 59
    if @enumeration.update_attributes(params[:enumeration])
54 60
      flash[:notice] = l(:notice_successful_update)
55
      redirect_to :action => 'list', :opt => @enumeration.opt
61
      redirect_to :action => 'list', :type => @enumeration.type
56 62
    else
57 63
      render :action => 'edit'
58 64
    end
......
65 71
      @enumeration.destroy
66 72
      redirect_to :action => 'index'
67 73
    elsif params[:reassign_to_id]
68
      if reassign_to = Enumeration.find_by_opt_and_id(@enumeration.opt, params[:reassign_to_id])
74
      if reassign_to = Enumeration.find_by_type_and_id(@enumeration.type, params[:reassign_to_id])
69 75
        @enumeration.destroy(reassign_to)
70 76
        redirect_to :action => 'index'
71 77
      end
72 78
    end
73
    @enumerations = Enumeration.values(@enumeration.opt) - [@enumeration]
79
    @enumerations = Enumeration.find(:all, :conditions => ['type = (?)', @enumeration.type]) - [@enumeration]
74 80
  #rescue
75 81
  #  flash[:error] = 'Unable to delete enumeration'
76 82
  #  redirect_to :action => 'index'
app/controllers/issues_controller.rb
102 102
    @changesets.reverse! if User.current.wants_comments_in_reverse_order?
103 103
    @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
104 104
    @edit_allowed = User.current.allowed_to?(:edit_issues, @project)
105
    @priorities = Enumeration.priorities
105
    @priorities = IssuePriority.all
106 106
    @time_entry = TimeEntry.new
107 107
    respond_to do |format|
108 108
      format.html { render :template => 'issues/show.rhtml' }
......
153 153
        return
154 154
      end		
155 155
    end	
156
    @priorities = Enumeration.priorities
156
    @priorities = IssuePriority.all
157 157
    render :layout => !request.xhr?
158 158
  end
159 159
  
......
163 163
  
164 164
  def edit
165 165
    @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
166
    @priorities = Enumeration.priorities
166
    @priorities = IssuePriority.all
167 167
    @edit_allowed = User.current.allowed_to?(:edit_issues, @project)
168 168
    @time_entry = TimeEntry.new
169 169
    
......
228 228
  def bulk_edit
229 229
    if request.post?
230 230
      status = params[:status_id].blank? ? nil : IssueStatus.find_by_id(params[:status_id])
231
      priority = params[:priority_id].blank? ? nil : Enumeration.find_by_id(params[:priority_id])
231
      priority = params[:priority_id].blank? ? nil : IssuePriority.find_by_id(params[:priority_id])
232 232
      assigned_to = (params[:assigned_to_id].blank? || params[:assigned_to_id] == 'none') ? nil : User.find_by_id(params[:assigned_to_id])
233 233
      category = (params[:category_id].blank? || params[:category_id] == 'none') ? nil : @project.issue_categories.find_by_id(params[:category_id])
234 234
      fixed_version = (params[:fixed_version_id].blank? || params[:fixed_version_id] == 'none') ? nil : @project.versions.find_by_id(params[:fixed_version_id])
......
407 407
      @assignables << @issue.assigned_to if @issue && @issue.assigned_to && !@assignables.include?(@issue.assigned_to)
408 408
    end
409 409
    
410
    @priorities = Enumeration.priorities.reverse
410
    @priorities = IssuePriority.all.reverse
411 411
    @statuses = IssueStatus.find(:all, :order => 'position')
412 412
    @back = request.env['HTTP_REFERER']
413 413
    
app/controllers/reports_controller.rb
37 37
      render :template => "reports/issue_report_details"
38 38
    when "priority"
39 39
      @field = "priority_id"
40
      @rows = Enumeration.priorities
40
      @rows = IssuePriority.all
41 41
      @data = issues_by_priority
42 42
      @report_title = l(:field_priority)
43 43
      render :template => "reports/issue_report_details"   
......
68 68
    else
69 69
      @trackers = @project.trackers
70 70
      @versions = @project.versions.sort
71
      @priorities = Enumeration.priorities
71
      @priorities = IssuePriority.all
72 72
      @categories = @project.issue_categories
73 73
      @assignees = @project.members.collect { |m| m.user }
74 74
      @authors = @project.members.collect { |m| m.user }
......
130 130
                                                  p.id as priority_id,
131 131
                                                  count(i.id) as total 
132 132
                                                from 
133
                                                  #{Issue.table_name} i, #{IssueStatus.table_name} s, #{Enumeration.table_name} p
133
                                                  #{Issue.table_name} i, #{IssueStatus.table_name} s, #{IssuePriority.table_name} p
134 134
                                                where 
135 135
                                                  i.status_id=s.id 
136 136
                                                  and i.priority_id=p.id
app/controllers/timelog_controller.rb
46 46
                                          :klass => Tracker,
47 47
                                          :label => :label_tracker},
48 48
                             'activity' => {:sql => "#{TimeEntry.table_name}.activity_id",
49
                                           :klass => Enumeration,
49
                                           :klass => TimeEntryActivity,
50 50
                                           :label => :label_activity},
51 51
                             'issue' => {:sql => "#{TimeEntry.table_name}.issue_id",
52 52
                                         :klass => Issue,
app/helpers/issues_helper.rb
78 78
        u = User.find_by_id(detail.value) and value = u.name if detail.value
79 79
        u = User.find_by_id(detail.old_value) and old_value = u.name if detail.old_value
80 80
      when 'priority_id'
81
        e = Enumeration.find_by_id(detail.value) and value = e.name if detail.value
82
        e = Enumeration.find_by_id(detail.old_value) and old_value = e.name if detail.old_value
81
        e = IssuePriority.find_by_id(detail.value) and value = e.name if detail.value
82
        e = IssuePriority.find_by_id(detail.old_value) and old_value = e.name if detail.old_value
83 83
      when 'category_id'
84 84
        c = IssueCategory.find_by_id(detail.value) and value = c.name if detail.value
85 85
        c = IssueCategory.find_by_id(detail.old_value) and old_value = c.name if detail.old_value
app/helpers/timelog_helper.rb
27 27
  end
28 28
  
29 29
  def activity_collection_for_select_options
30
    activities = Enumeration.activities
30
    activities = TimeEntryActivity.all
31 31
    collection = []
32 32
    collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ] unless activities.detect(&:is_default)
33 33
    activities.each { |a| collection << [a.name, a.id] }
app/models/document.rb
17 17

  
18 18
class Document < ActiveRecord::Base
19 19
  belongs_to :project
20
  belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id"
20
  belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id"
21 21
  acts_as_attachable :delete_permission => :manage_documents
22 22

  
23 23
  acts_as_searchable :columns => ['title', "#{table_name}.description"], :include => :project
......
31 31
  
32 32
  def after_initialize
33 33
    if new_record?
34
      self.category ||= Enumeration.document_categories.default
34
      self.category ||= DocumentCategory.default
35 35
    end
36 36
  end
37 37
end
app/models/document_category.rb
1
# redMine - project management software
2
# Copyright (C) 2006  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
# 
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
# 
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
class DocumentCategory < Enumeration
19
  has_many :documents, :foreign_key => 'category_id'
20

  
21
  OptionName = :enumeration_doc_categories
22
  # Backwards compatiblity.  Can be removed post-0.9
23
  OptName = 'DCAT'
24

  
25
  def option_name
26
    OptionName
27
  end
28

  
29
  def objects_count
30
    documents.count
31
  end
32

  
33
  def transfer_relations(to)
34
    documents.update_all("category_id = #{to.id}")
35
  end
36
end
app/models/enumeration.rb
16 16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 17

  
18 18
class Enumeration < ActiveRecord::Base
19
  acts_as_list :scope => 'opt = \'#{opt}\''
19
  acts_as_list :scope => 'type = \'#{type}\''
20 20

  
21 21
  before_destroy :check_integrity
22 22
  
23
  validates_presence_of :opt, :name
24
  validates_uniqueness_of :name, :scope => [:opt]
23
  validates_presence_of :name
24
  validates_uniqueness_of :name, :scope => [:type]
25 25
  validates_length_of :name, :maximum => 30
26

  
27
  # Single table inheritance would be an option
28
  OPTIONS = {
29
    "IPRI" => {:label => :enumeration_issue_priorities, :model => Issue, :foreign_key => :priority_id, :scope => :priorities},
30
    "DCAT" => {:label => :enumeration_doc_categories, :model => Document, :foreign_key => :category_id, :scope => :document_categories},
31
    "ACTI" => {:label => :enumeration_activities, :model => TimeEntry, :foreign_key => :activity_id, :scope => :activities}
32
  }.freeze
33 26
  
34
  # Creates a named scope for each type of value. The scope has a +default+ method
35
  # that returns the default value, or nil if no value is set as default.
36
  # Example:
37
  #   Enumeration.priorities
38
  #   Enumeration.priorities.default
39
  OPTIONS.each do |k, v|
40
    next unless v[:scope]
41
    named_scope v[:scope], :conditions => { :opt => k }, :order => 'position' do
42
      def default
43
        find(:first, :conditions => { :is_default => true })
44
      end
27
  # Backwards compatiblity named_scopes.
28
  # Can be removed post-0.9
29
  named_scope :priorities, :conditions => { :type => "IssuePriority" }, :order => 'position' do
30
    ActiveSupport::Deprecation.warn("Enumeration#priorities is deprecated, use the IssuePriority class. (#{Redmine::Info.issue(3007)})")
31
    def default
32
      find(:first, :conditions => { :is_default => true })
33
    end
34
  end
35

  
36
  named_scope :document_categories, :conditions => { :type => "DocumentCategory" }, :order => 'position' do
37
    ActiveSupport::Deprecation.warn("Enumeration#document_categories is deprecated, use the DocumentCategories class. (#{Redmine::Info.issue(3007)})")
38
    def default
39
      find(:first, :conditions => { :is_default => true })
40
    end
41
  end
42

  
43
  named_scope :activities, :conditions => { :type => "TimeEntryActivity" }, :order => 'position' do
44
    ActiveSupport::Deprecation.warn("Enumeration#activities is deprecated, use the TimeEntryActivity class. (#{Redmine::Info.issue(3007)})")
45
    def default
46
      find(:first, :conditions => { :is_default => true })
45 47
    end
46 48
  end
47 49
  
48
  named_scope :values, lambda {|opt| { :conditions => { :opt => opt }, :order => 'position' } } do
50
  named_scope :values, lambda {|type| { :conditions => { :type => type }, :order => 'position' } } do
49 51
    def default
50 52
      find(:first, :conditions => { :is_default => true })
51 53
    end
52 54
  end
53 55

  
56
  named_scope :all, :order => 'position'
57

  
58
  def self.default
59
    # Creates a fake default scope so Enumeration.default will check
60
    # it's type.  STI subclasses will automatically add their own
61
    # types to the finder.
62
    if self.descends_from_active_record?
63
      find(:first, :conditions => { :is_default => true, :type => 'Enumeration' })
64
    else
65
      # STI classes are
66
      find(:first, :conditions => { :is_default => true })
67
    end
68
  end
69
  
70
  # Overloaded on concrete classes
54 71
  def option_name
55
    OPTIONS[self.opt][:label]
72
    nil
73
  end
74

  
75
  # Backwards compatiblity.  Can be removed post-0.9
76
  def opt
77
    ActiveSupport::Deprecation.warn("Enumeration#opt is deprecated, use the STI classes now. (#{Redmine::Info.issue(3007)})")
78
    return OptName
56 79
  end
57 80

  
58 81
  def before_save
59 82
    if is_default? && is_default_changed?
60
      Enumeration.update_all("is_default = #{connection.quoted_false}", {:opt => opt})
83
      Enumeration.update_all("is_default = #{connection.quoted_false}", {:type => type})
61 84
    end
62 85
  end
63 86
  
87
  # Overloaded on concrete classes
64 88
  def objects_count
65
    OPTIONS[self.opt][:model].count(:conditions => "#{OPTIONS[self.opt][:foreign_key]} = #{id}")
89
    0
66 90
  end
67 91
  
68 92
  def in_use?
......
75 99
  # If a enumeration is specified, objects are reassigned
76 100
  def destroy(reassign_to = nil)
77 101
    if reassign_to && reassign_to.is_a?(Enumeration)
78
      OPTIONS[self.opt][:model].update_all("#{OPTIONS[self.opt][:foreign_key]} = #{reassign_to.id}", "#{OPTIONS[self.opt][:foreign_key]} = #{id}")
102
      self.transfer_relations(reassign_to)
79 103
    end
80 104
    destroy_without_reassign
81 105
  end
......
85 109
  end
86 110
  
87 111
  def to_s; name end
112

  
113
  # Returns the Subclasses of Enumeration.  Each Subclass needs to be
114
  # required in development mode.
115
  #
116
  # Note: subclasses is protected in ActiveRecord
117
  def self.get_subclasses
118
    @@subclasses[Enumeration]
119
  end
88 120
  
89 121
private
90 122
  def check_integrity
91 123
    raise "Can't delete enumeration" if self.in_use?
92 124
  end
125

  
93 126
end
127

  
128
# Force load the subclasses in development mode
129
require_dependency 'time_entry_activity'
130
require_dependency 'document_category'
131
require_dependency 'issue_priority'
app/models/issue.rb
22 22
  belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
23 23
  belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
24 24
  belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
25
  belongs_to :priority, :class_name => 'Enumeration', :foreign_key => 'priority_id'
25
  belongs_to :priority, :class_name => 'IssuePriority', :foreign_key => 'priority_id'
26 26
  belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
27 27

  
28 28
  has_many :journals, :as => :journalized, :dependent => :destroy
......
65 65
    if new_record?
66 66
      # set default values for new records only
67 67
      self.status ||= IssueStatus.default
68
      self.priority ||= Enumeration.priorities.default
68
      self.priority ||= IssuePriority.default
69 69
    end
70 70
  end
71 71
  
app/models/issue_priority.rb
1
# redMine - project management software
2
# Copyright (C) 2006  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
# 
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
# 
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
class IssuePriority < Enumeration
19
  has_many :issues, :foreign_key => 'priority_id'
20

  
21
  OptionName = :enumeration_issue_priorities
22
  # Backwards compatiblity.  Can be removed post-0.9
23
  OptName = 'IPRI'
24

  
25
  def option_name
26
    OptionName
27
  end
28

  
29
  def objects_count
30
    issues.count
31
  end
32

  
33
  def transfer_relations(to)
34
    issues.update_all("priority_id = #{to.id}")
35
  end
36
end
app/models/mail_handler.rb
91 91
    project = target_project
92 92
    tracker = (get_keyword(:tracker) && project.trackers.find_by_name(get_keyword(:tracker))) || project.trackers.find(:first)
93 93
    category = (get_keyword(:category) && project.issue_categories.find_by_name(get_keyword(:category)))
94
    priority = (get_keyword(:priority) && Enumeration.find_by_opt_and_name('IPRI', get_keyword(:priority)))
94
    priority = (get_keyword(:priority) && IssuePriority.find_by_name(get_keyword(:priority)))
95 95
    status =  (get_keyword(:status) && IssueStatus.find_by_name(get_keyword(:status)))
96 96

  
97 97
    # check permission
app/models/query.rb
101 101
    QueryColumn.new(:project, :sortable => "#{Project.table_name}.name"),
102 102
    QueryColumn.new(:tracker, :sortable => "#{Tracker.table_name}.position"),
103 103
    QueryColumn.new(:status, :sortable => "#{IssueStatus.table_name}.position"),
104
    QueryColumn.new(:priority, :sortable => "#{Enumeration.table_name}.position", :default_order => 'desc'),
104
    QueryColumn.new(:priority, :sortable => "#{IssuePriority.table_name}.position", :default_order => 'desc'),
105 105
    QueryColumn.new(:subject, :sortable => "#{Issue.table_name}.subject"),
106 106
    QueryColumn.new(:author),
107 107
    QueryColumn.new(:assigned_to, :sortable => ["#{User.table_name}.lastname", "#{User.table_name}.firstname"]),
......
151 151
    
152 152
    @available_filters = { "status_id" => { :type => :list_status, :order => 1, :values => IssueStatus.find(:all, :order => 'position').collect{|s| [s.name, s.id.to_s] } },       
153 153
                           "tracker_id" => { :type => :list, :order => 2, :values => trackers.collect{|s| [s.name, s.id.to_s] } },                                                                                                                
154
                           "priority_id" => { :type => :list, :order => 3, :values => Enumeration.find(:all, :conditions => ['opt=?','IPRI'], :order => 'position').collect{|s| [s.name, s.id.to_s] } },
154
                           "priority_id" => { :type => :list, :order => 3, :values => IssuePriority.all.collect{|s| [s.name, s.id.to_s] } },
155 155
                           "subject" => { :type => :text, :order => 8 },  
156 156
                           "created_on" => { :type => :date_past, :order => 9 },                        
157 157
                           "updated_on" => { :type => :date_past, :order => 10 },
app/models/time_entry.rb
21 21
  belongs_to :project
22 22
  belongs_to :issue
23 23
  belongs_to :user
24
  belongs_to :activity, :class_name => 'Enumeration', :foreign_key => :activity_id
24
  belongs_to :activity, :class_name => 'TimeEntryActivity', :foreign_key => 'activity_id'
25 25
  
26 26
  attr_protected :project_id, :user_id, :tyear, :tmonth, :tweek
27 27

  
......
37 37

  
38 38
  def after_initialize
39 39
    if new_record? && self.activity.nil?
40
      if default_activity = Enumeration.activities.default
40
      if default_activity = TimeEntryActivity.default
41 41
        self.activity_id = default_activity.id
42 42
      end
43 43
    end
app/models/time_entry_activity.rb
1
# redMine - project management software
2
# Copyright (C) 2006  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
# 
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
# 
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
class TimeEntryActivity < Enumeration
19
  has_many :time_entries, :foreign_key => 'activity_id'
20

  
21
  OptionName = :enumeration_activities
22
  # Backwards compatiblity.  Can be removed post-0.9
23
  OptName = 'ACTI'
24
  
25
  def option_name
26
    OptionName
27
  end
28

  
29
  def objects_count
30
    time_entries.count
31
  end
32

  
33
  def transfer_relations(to)
34
    time_entries.update_all("activity_id = #{to.id}")
35
  end
36
end
app/views/documents/_form.rhtml
2 2
<div class="box">
3 3
<!--[form:document]-->
4 4
<p><label for="document_category_id"><%=l(:field_category)%></label>
5
<%= select('document', 'category_id', Enumeration.document_categories.collect {|c| [c.name, c.id]}) %></p>
5
<%= select('document', 'category_id', DocumentCategory.all.collect {|c| [c.name, c.id]}) %></p>
6 6

  
7 7
<p><label for="document_title"><%=l(:field_title)%> <span class="required">*</span></label>
8 8
<%= text_field 'document', 'title', :size => 60 %></p>
app/views/enumerations/_form.rhtml
1 1
<%= error_messages_for 'enumeration' %>
2 2
<div class="box">
3 3
<!--[form:optvalue]-->
4
<%= hidden_field 'enumeration', 'opt'  %>
4
<%= hidden_field 'enumeration', 'type'  %>
5 5

  
6 6
<p><label for="enumeration_name"><%=l(:field_name)%></label>
7 7
<%= text_field 'enumeration', 'name'  %></p>
app/views/enumerations/list.rhtml
1 1
<h2><%=l(:label_enumerations)%></h2>
2 2

  
3
<% Enumeration::OPTIONS.each do |option, params| %>
4
<h3><%= l(params[:label]) %></h3>
3
<% Enumeration.get_subclasses.each do |klass| %>
4
<h3><%= l(klass::OptionName) %></h3>
5 5

  
6
<% enumerations = Enumeration.values(option) %>
6
<% enumerations = klass.all %>
7 7
<% if enumerations.any? %>
8 8
<table class="list">
9 9
<% enumerations.each do |enumeration| %>
......
20 20
<% reset_cycle %>
21 21
<% end %>
22 22

  
23
<p><%= link_to l(:label_enumeration_new), { :action => 'new', :opt => option } %></p>
23
<p><%= link_to l(:label_enumeration_new), { :action => 'new', :type => klass.name } %></p>
24 24
<% end %>
25 25

  
26 26
<% html_title(l(:label_enumerations)) -%>
app/views/issues/bulk_edit.rhtml
13 13
<%= select_tag('status_id', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@available_statuses, :id, :name)) %></label>
14 14
<% end %>
15 15
<label><%= l(:field_priority) %>: 
16
<%= select_tag('priority_id', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(Enumeration.priorities, :id, :name)) %></label>
16
<%= select_tag('priority_id', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(IssuePriority.all, :id, :name)) %></label>
17 17
<label><%= l(:field_category) %>: 
18 18
<%= select_tag('category_id', content_tag('option', l(:label_no_change_option), :value => '') +
19 19
                                content_tag('option', l(:label_none), :value => 'none') +
app/views/my/blocks/_issuesassignedtome.rhtml
4 4
                                :conditions => {:assigned_to_id => User.current.id},
5 5
                                :limit => 10, 
6 6
                                :include => [ :status, :project, :tracker, :priority ], 
7
                                :order => "#{Enumeration.table_name}.position DESC, #{Issue.table_name}.updated_on DESC") %>
7
                                :order => "#{IssuePriority.table_name}.position DESC, #{Issue.table_name}.updated_on DESC") %>
8 8
<%= render :partial => 'issues/list_simple', :locals => { :issues => assigned_issues } %>
9 9
<% if assigned_issues.length > 0 %>
10 10
<p class="small"><%= link_to l(:label_issue_view_all), :controller => 'issues',
db/migrate/20090323224724_add_type_to_enumerations.rb
1
class AddTypeToEnumerations < ActiveRecord::Migration
2
  def self.up
3
    add_column :enumerations, :type, :string
4
  end
5

  
6
  def self.down
7
    remove_column :enumerations, :type
8
  end
9
end
db/migrate/20090401221305_update_enumerations_to_sti.rb
1
class UpdateEnumerationsToSti < ActiveRecord::Migration
2
  def self.up
3
    Enumeration.update_all("type = 'IssuePriority'", "opt = 'IPRI'")
4
    Enumeration.update_all("type = 'DocumentCategory'", "opt = 'DCAT'")
5
    Enumeration.update_all("type = 'TimeEntryActivity'", "opt = 'ACTI'")
6
  end
7

  
8
  def self.down
9
    # no-op
10
  end
11
end
lib/redmine/info.rb
5 5
      def url; 'http://www.redmine.org/' end
6 6
      def help_url; 'http://www.redmine.org/guide' end
7 7
      def versioned_name; "#{app_name} #{Redmine::VERSION}" end
8

  
9
      # Creates the url string to a specific Redmine issue
10
      def issue(issue_id)
11
        url + 'issues/' + issue_id.to_s
12
      end
8 13
    end
9 14
  end
10 15
end
test/fixtures/enumerations.yml
3 3
  name: Uncategorized
4 4
  id: 1
5 5
  opt: DCAT
6
  type: DocumentCategory
6 7
enumerations_002: 
7 8
  name: User documentation
8 9
  id: 2
9 10
  opt: DCAT
11
  type: DocumentCategory
10 12
enumerations_003: 
11 13
  name: Technical documentation
12 14
  id: 3
13 15
  opt: DCAT
16
  type: DocumentCategory
14 17
enumerations_004: 
15 18
  name: Low
16 19
  id: 4
17 20
  opt: IPRI
21
  type: IssuePriority
18 22
enumerations_005: 
19 23
  name: Normal
20 24
  id: 5
21 25
  opt: IPRI
26
  type: IssuePriority
22 27
  is_default: true
23 28
enumerations_006: 
24 29
  name: High
25 30
  id: 6
26 31
  opt: IPRI
32
  type: IssuePriority
27 33
enumerations_007: 
28 34
  name: Urgent
29 35
  id: 7
30 36
  opt: IPRI
37
  type: IssuePriority
31 38
enumerations_008: 
32 39
  name: Immediate
33 40
  id: 8
34 41
  opt: IPRI
42
  type: IssuePriority
35 43
enumerations_009: 
36 44
  name: Design
37 45
  id: 9
38 46
  opt: ACTI
47
  type: TimeEntryActivity
39 48
enumerations_010: 
40 49
  name: Development
41 50
  id: 10
42 51
  opt: ACTI
52
  type: TimeEntryActivity
43 53
  is_default: true
44 54
enumerations_011: 
45 55
  name: QA
46 56
  id: 11
47 57
  opt: ACTI
48
  
58
  type: TimeEntryActivity
59
enumerations_012:
60
  name: Default Enumeration
61
  id: 12
62
  opt: ''
63
  type: Enumeration
64
  is_default: true
65
enumerations_013:
66
  name: Another Enumeration
67
  id: 13
68
  opt: ''
69
  type: Enumeration
test/fixtures/issues.yml
95 95
  created_on: <%= 10.days.ago.to_date.to_s(:db) %>
96 96
  project_id: 1
97 97
  updated_on: <%= 10.days.ago.to_date.to_s(:db) %>
98
  priority_id: 3
98
  priority_id: 5
99 99
  subject: Issue due today
100 100
  id: 7
101 101
  fixed_version_id: 
......
112 112
  created_on: <%= 10.days.ago.to_date.to_s(:db) %>
113 113
  project_id: 1
114 114
  updated_on: <%= 10.days.ago.to_date.to_s(:db) %>
115
  priority_id: 3
115
  priority_id: 5
116 116
  subject: Closed issue
117 117
  id: 8
118 118
  fixed_version_id: 
test/functional/issues_controller_test.rb
670 670
           :id => 1,
671 671
           :issue => { :status_id => 2, :assigned_to_id => 3 },
672 672
           :notes => 'Assigned to dlopper',
673
           :time_entry => { :hours => '', :comments => '', :activity_id => Enumeration.activities.first }
673
           :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
674 674
    end
675 675
    assert_redirected_to :action => 'show', :id => '1'
676 676
    issue.reload
......
706 706
      post :edit,
707 707
           :id => 1,
708 708
           :notes => '2.5 hours added',
709
           :time_entry => { :hours => '2.5', :comments => '', :activity_id => Enumeration.activities.first }
709
           :time_entry => { :hours => '2.5', :comments => '', :activity_id => TimeEntryActivity.first }
710 710
    end
711 711
    assert_redirected_to :action => 'show', :id => '1'
712 712
    
test/integration/issues_test.rb
41 41
    
42 42
    post 'projects/1/issues', :tracker_id => "1",
43 43
                                 :issue => { :start_date => "2006-12-26", 
44
                                             :priority_id => "3", 
44
                                             :priority_id => "4", 
45 45
                                             :subject => "new test issue", 
46 46
                                             :category_id => "", 
47 47
                                             :description => "new issue", 
test/unit/document_category_test.rb
1
# redMine - project management software
2
# Copyright (C) 2006-2008  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
# 
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
# 
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require File.dirname(__FILE__) + '/../test_helper'
19

  
20
class DocumentCategoryTest < Test::Unit::TestCase
21
  fixtures :enumerations, :documents
22

  
23
  def test_should_be_an_enumeration
24
    assert DocumentCategory.ancestors.include?(Enumeration)
25
  end
26
  
27
  def test_objects_count
28
    assert_equal 1, DocumentCategory.find_by_name("Uncategorized").objects_count
29
    assert_equal 0, DocumentCategory.find_by_name("User documentation").objects_count
30
  end
31

  
32
  def test_option_name
33
    assert_equal :enumeration_doc_categories, DocumentCategory.new.option_name
34
  end
35
end
36

  
test/unit/enumeration_test.rb
38 38
  end
39 39
  
40 40
  def test_default
41
    e = Enumeration.priorities.default
41
    e = Enumeration.default
42 42
    assert e.is_a?(Enumeration)
43 43
    assert e.is_default?
44
    assert_equal 'Normal', e.name
44
    assert_equal 'Default Enumeration', e.name
45 45
  end
46 46
  
47 47
  def test_create
48
    e = Enumeration.new(:opt => 'IPRI', :name => 'Very urgent', :is_default => false)
48
    e = Enumeration.new(:name => 'Not default', :is_default => false)
49
    e.type = 'Enumeration'
49 50
    assert e.save
50
    assert_equal 'Normal', Enumeration.priorities.default.name
51
    assert_equal 'Default Enumeration', Enumeration.default.name
51 52
  end
52 53
  
53 54
  def test_create_as_default
54
    e = Enumeration.new(:opt => 'IPRI', :name => 'Very urgent', :is_default => true)
55
    e = Enumeration.new(:name => 'Very urgent', :is_default => true)
56
    e.type = 'Enumeration'
55 57
    assert e.save
56
    assert_equal e, Enumeration.priorities.default
58
    assert_equal e, Enumeration.default
57 59
  end
58 60
  
59 61
  def test_update_default
60
    e = Enumeration.priorities.default
62
    e = Enumeration.default
61 63
    e.update_attributes(:name => 'Changed', :is_default => true)
62
    assert_equal e, Enumeration.priorities.default
64
    assert_equal e, Enumeration.default
63 65
  end
64 66
  
65 67
  def test_update_default_to_non_default
66
    e = Enumeration.priorities.default
68
    e = Enumeration.default
67 69
    e.update_attributes(:name => 'Changed', :is_default => false)
68
    assert_nil Enumeration.priorities.default
70
    assert_nil Enumeration.default
69 71
  end
70 72
  
71 73
  def test_change_default
72
    e = Enumeration.find_by_name('Urgent')
73
    e.update_attributes(:name => 'Urgent', :is_default => true)
74
    assert_equal e, Enumeration.priorities.default
74
    e = Enumeration.find_by_name('Default Enumeration')
75
    e.update_attributes(:name => 'Changed Enumeration', :is_default => true)
76
    assert_equal e, Enumeration.default
75 77
  end
76 78
  
77 79
  def test_destroy_with_reassign
test/unit/issue_priority_test.rb
1
# redMine - project management software
2
# Copyright (C) 2006-2008  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
# 
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
# 
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require File.dirname(__FILE__) + '/../test_helper'
19

  
20
class IssuePriorityTest < Test::Unit::TestCase
21
  fixtures :enumerations, :issues
22

  
23
  def test_should_be_an_enumeration
24
    assert IssuePriority.ancestors.include?(Enumeration)
25
  end
26
  
27
  def test_objects_count
28
    # low priority
29
    assert_equal 5, IssuePriority.find(4).objects_count
30
    # urgent
31
    assert_equal 0, IssuePriority.find(7).objects_count
32
  end
33

  
34
  def test_option_name
35
    assert_equal :enumeration_issue_priorities, IssuePriority.new.option_name
36
  end
37
end
38

  
test/unit/issue_test.rb
27 27
           :time_entries
28 28

  
29 29
  def test_create
30
    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.priorities.first, :subject => 'test_create', :description => 'IssueTest#test_create', :estimated_hours => '1:30')
30
    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'test_create', :description => 'IssueTest#test_create', :estimated_hours => '1:30')
31 31
    assert issue.save
32 32
    issue.reload
33 33
    assert_equal 1.5, issue.estimated_hours
34 34
  end
35 35
  
36 36
  def test_create_minimal
37
    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.priorities.first, :subject => 'test_create')
37
    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'test_create')
38 38
    assert issue.save
39 39
    assert issue.description.nil?
40 40
  end
......
123 123
  end
124 124
  
125 125
  def test_category_based_assignment
126
    issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.priorities.first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1)
126
    issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1)
127 127
    assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
128 128
  end
129 129
  
......
139 139
  
140 140
  def test_should_close_duplicates
141 141
    # Create 3 issues
142
    issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => Enumeration.priorities.first, :subject => 'Duplicates test', :description => 'Duplicates test')
142
    issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'Duplicates test', :description => 'Duplicates test')
143 143
    assert issue1.save
144 144
    issue2 = issue1.clone
145 145
    assert issue2.save
......
166 166
  
167 167
  def test_should_not_close_duplicated_issue
168 168
    # Create 3 issues
169
    issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => Enumeration.priorities.first, :subject => 'Duplicates test', :description => 'Duplicates test')
169
    issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'Duplicates test', :description => 'Duplicates test')
170 170
    assert issue1.save
171 171
    issue2 = issue1.clone
172 172
    assert issue2.save
test/unit/time_entry_activity_test.rb
1
# redMine - project management software
2
# Copyright (C) 2006-2008  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
# 
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
# 
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require File.dirname(__FILE__) + '/../test_helper'
19

  
20
class TimeEntryActivityTest < Test::Unit::TestCase
21
  fixtures :enumerations, :time_entries
22

  
23
  def test_should_be_an_enumeration
24
    assert TimeEntryActivity.ancestors.include?(Enumeration)
25
  end
26
  
27
  def test_objects_count
28
    assert_equal 3, TimeEntryActivity.find_by_name("Design").objects_count
29
    assert_equal 1, TimeEntryActivity.find_by_name("Development").objects_count
30
  end
31

  
32
  def test_option_name
33
    assert_equal :enumeration_activities, TimeEntryActivity.new.option_name
34
  end
35
end
36