##// END OF EJS Templates
Fixed: 500 error when validation fails on issue edition with no custom fields....
Jean-Philippe Lang -
r970:bd8eded6702a
parent child
Show More
@@ -1,250 +1,251
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
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 18 class IssuesController < ApplicationController
19 19 layout 'base'
20 20 before_filter :find_project, :authorize, :except => [:index, :changes, :preview]
21 21 before_filter :find_optional_project, :only => [:index, :changes]
22 22 accept_key_auth :index, :changes
23 23
24 24 cache_sweeper :issue_sweeper, :only => [ :edit, :change_status, :destroy ]
25 25
26 26 helper :projects
27 27 include ProjectsHelper
28 28 helper :custom_fields
29 29 include CustomFieldsHelper
30 30 helper :ifpdf
31 31 include IfpdfHelper
32 32 helper :issue_relations
33 33 include IssueRelationsHelper
34 34 helper :watchers
35 35 include WatchersHelper
36 36 helper :attachments
37 37 include AttachmentsHelper
38 38 helper :queries
39 39 helper :sort
40 40 include SortHelper
41 41 include IssuesHelper
42 42
43 43 def index
44 44 sort_init "#{Issue.table_name}.id", "desc"
45 45 sort_update
46 46 retrieve_query
47 47 if @query.valid?
48 48 limit = %w(pdf csv).include?(params[:format]) ? Setting.issues_export_limit.to_i : 25
49 49 @issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
50 50 @issue_pages = Paginator.new self, @issue_count, limit, params['page']
51 51 @issues = Issue.find :all, :order => sort_clause,
52 52 :include => [ :assigned_to, :status, :tracker, :project, :priority, :category, :fixed_version ],
53 53 :conditions => @query.statement,
54 54 :limit => limit,
55 55 :offset => @issue_pages.current.offset
56 56 respond_to do |format|
57 57 format.html { render :template => 'issues/index.rhtml', :layout => !request.xhr? }
58 58 format.atom { render_feed(@issues, :title => l(:label_issue_plural)) }
59 59 format.csv { send_data(issues_to_csv(@issues, @project).read, :type => 'text/csv; header=present', :filename => 'export.csv') }
60 60 format.pdf { send_data(render(:template => 'issues/index.rfpdf', :layout => false), :type => 'application/pdf', :filename => 'export.pdf') }
61 61 end
62 62 else
63 63 # Send html if the query is not valid
64 64 render(:template => 'issues/index.rhtml', :layout => !request.xhr?)
65 65 end
66 66 end
67 67
68 68 def changes
69 69 sort_init "#{Issue.table_name}.id", "desc"
70 70 sort_update
71 71 retrieve_query
72 72 if @query.valid?
73 73 @changes = Journal.find :all, :include => [ :details, :user, {:issue => [:project, :author, :tracker, :status]} ],
74 74 :conditions => @query.statement,
75 75 :limit => 25,
76 76 :order => "#{Journal.table_name}.created_on DESC"
77 77 end
78 78 @title = (@project ? @project.name : Setting.app_title) + ": " + (@query.new_record? ? l(:label_changes_details) : @query.name)
79 79 render :layout => false, :content_type => 'application/atom+xml'
80 80 end
81 81
82 82 def show
83 83 @custom_values = @issue.custom_values.find(:all, :include => :custom_field, :order => "#{CustomField.table_name}.position")
84 84 @journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
85 85 @status_options = @issue.status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker)
86 86 respond_to do |format|
87 87 format.html { render :template => 'issues/show.rhtml' }
88 88 format.pdf { send_data(render(:template => 'issues/show.rfpdf', :layout => false), :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf") }
89 89 end
90 90 end
91 91
92 92 def edit
93 93 @priorities = Enumeration::get_values('IPRI')
94 @custom_values = []
94 95 if request.get?
95 96 @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x, :customized => @issue) }
96 97 else
97 98 begin
98 99 @issue.init_journal(User.current)
99 100 # Retrieve custom fields and values
100 101 if params["custom_fields"]
101 102 @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
102 103 @issue.custom_values = @custom_values
103 104 end
104 105 @issue.attributes = params[:issue]
105 106 if @issue.save
106 107 flash[:notice] = l(:notice_successful_update)
107 108 redirect_to(params[:back_to] || {:action => 'show', :id => @issue})
108 109 end
109 110 rescue ActiveRecord::StaleObjectError
110 111 # Optimistic locking exception
111 112 flash[:error] = l(:notice_locking_conflict)
112 113 end
113 114 end
114 115 end
115 116
116 117 def add_note
117 118 journal = @issue.init_journal(User.current, params[:notes])
118 119 params[:attachments].each { |file|
119 120 next unless file.size > 0
120 121 a = Attachment.create(:container => @issue, :file => file, :author => User.current)
121 122 journal.details << JournalDetail.new(:property => 'attachment',
122 123 :prop_key => a.id,
123 124 :value => a.filename) unless a.new_record?
124 125 } if params[:attachments] and params[:attachments].is_a? Array
125 126 if journal.save
126 127 flash[:notice] = l(:notice_successful_update)
127 128 Mailer.deliver_issue_edit(journal) if Setting.notified_events.include?('issue_updated')
128 129 redirect_to :action => 'show', :id => @issue
129 130 return
130 131 end
131 132 show
132 133 end
133 134
134 135 def change_status
135 136 @status_options = @issue.status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker)
136 137 @new_status = IssueStatus.find(params[:new_status_id])
137 138 if params[:confirm]
138 139 begin
139 140 journal = @issue.init_journal(User.current, params[:notes])
140 141 @issue.status = @new_status
141 142 if @issue.update_attributes(params[:issue])
142 143 # Save attachments
143 144 params[:attachments].each { |file|
144 145 next unless file.size > 0
145 146 a = Attachment.create(:container => @issue, :file => file, :author => User.current)
146 147 journal.details << JournalDetail.new(:property => 'attachment',
147 148 :prop_key => a.id,
148 149 :value => a.filename) unless a.new_record?
149 150 } if params[:attachments] and params[:attachments].is_a? Array
150 151
151 152 # Log time
152 153 if current_role.allowed_to?(:log_time)
153 154 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
154 155 @time_entry.attributes = params[:time_entry]
155 156 @time_entry.save
156 157 end
157 158
158 159 flash[:notice] = l(:notice_successful_update)
159 160 Mailer.deliver_issue_edit(journal) if Setting.notified_events.include?('issue_updated')
160 161 redirect_to :action => 'show', :id => @issue
161 162 end
162 163 rescue ActiveRecord::StaleObjectError
163 164 # Optimistic locking exception
164 165 flash[:error] = l(:notice_locking_conflict)
165 166 end
166 167 end
167 168 @assignable_to = @project.members.find(:all, :include => :user).collect{ |m| m.user }
168 169 @activities = Enumeration::get_values('ACTI')
169 170 end
170 171
171 172 def destroy
172 173 @issue.destroy
173 174 redirect_to :action => 'index', :project_id => @project
174 175 end
175 176
176 177 def destroy_attachment
177 178 a = @issue.attachments.find(params[:attachment_id])
178 179 a.destroy
179 180 journal = @issue.init_journal(User.current)
180 181 journal.details << JournalDetail.new(:property => 'attachment',
181 182 :prop_key => a.id,
182 183 :old_value => a.filename)
183 184 journal.save
184 185 redirect_to :action => 'show', :id => @issue
185 186 end
186 187
187 188 def context_menu
188 189 @priorities = Enumeration.get_values('IPRI').reverse
189 190 @statuses = IssueStatus.find(:all, :order => 'position')
190 191 @allowed_statuses = @issue.status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker)
191 192 @assignables = @issue.assignable_users
192 193 @assignables << @issue.assigned_to if @issue.assigned_to && !@assignables.include?(@issue.assigned_to)
193 194 @can = {:edit => User.current.allowed_to?(:edit_issues, @project),
194 195 :change_status => User.current.allowed_to?(:change_issue_status, @project),
195 196 :add => User.current.allowed_to?(:add_issues, @project),
196 197 :move => User.current.allowed_to?(:move_issues, @project),
197 198 :copy => (@project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
198 199 :delete => User.current.allowed_to?(:delete_issues, @project)}
199 200 render :layout => false
200 201 end
201 202
202 203 def preview
203 204 issue = Issue.find_by_id(params[:id])
204 205 @attachements = issue.attachments if issue
205 206 @text = params[:issue][:description]
206 207 render :partial => 'common/preview'
207 208 end
208 209
209 210 private
210 211 def find_project
211 212 @issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category])
212 213 @project = @issue.project
213 214 rescue ActiveRecord::RecordNotFound
214 215 render_404
215 216 end
216 217
217 218 def find_optional_project
218 219 return true unless params[:project_id]
219 220 @project = Project.find(params[:project_id])
220 221 authorize
221 222 rescue ActiveRecord::RecordNotFound
222 223 render_404
223 224 end
224 225
225 226 # Retrieve query from session or build a new query
226 227 def retrieve_query
227 228 if params[:query_id]
228 229 @query = Query.find(params[:query_id], :conditions => {:project_id => (@project ? @project.id : nil)})
229 230 session[:query] = @query
230 231 else
231 232 if params[:set_filter] or !session[:query] or session[:query].project != @project
232 233 # Give it a name, required to be valid
233 234 @query = Query.new(:name => "_")
234 235 @query.project = @project
235 236 if params[:fields] and params[:fields].is_a? Array
236 237 params[:fields].each do |field|
237 238 @query.add_filter(field, params[:operators][field], params[:values][field])
238 239 end
239 240 else
240 241 @query.available_filters.keys.each do |field|
241 242 @query.add_short_filter(field, params[field]) if params[field]
242 243 end
243 244 end
244 245 session[:query] = @query
245 246 else
246 247 @query = session[:query]
247 248 end
248 249 end
249 250 end
250 251 end
General Comments 0
You need to be logged in to leave comments. Login now