From 5f185b6c0532595e4a165600db9f99c5475289bb Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Sat, 9 Sep 2006 16:07:02 +0000 Subject: [PATCH] data locking for issues git-svn-id: http://redmine.rubyforge.org/svn/trunk@23 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- redmine/app/controllers/issues_controller.rb | 109 ++++++++++--------- redmine/app/views/issues/change_status.rhtml | 3 +- redmine/app/views/issues/edit.rhtml | 2 +- redmine/app/views/issues/show.rhtml | 2 +- redmine/db/migrate/001_setup.rb | 3 +- redmine/lang/de.yml | 1 + redmine/lang/en.yml | 1 + redmine/lang/es.yml | 1 + redmine/lang/fr.yml | 1 + 9 files changed, 67 insertions(+), 56 deletions(-) diff --git a/redmine/app/controllers/issues_controller.rb b/redmine/app/controllers/issues_controller.rb index 07f2c7736..9452995fb 100644 --- a/redmine/app/controllers/issues_controller.rb +++ b/redmine/app/controllers/issues_controller.rb @@ -16,61 +16,66 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class IssuesController < ApplicationController - layout 'base' - before_filter :find_project, :authorize + layout 'base' + before_filter :find_project, :authorize - helper :custom_fields - include CustomFieldsHelper - - def show - @status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", self.logged_in_user.role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if self.logged_in_user - @custom_values = @issue.custom_values.find(:all, :include => :custom_field) - end + helper :custom_fields + include CustomFieldsHelper - def edit - @priorities = Enumeration::get_values('IPRI') - - if request.get? - @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) } - else - # Retrieve custom fields and values - @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]) } - @issue.custom_values = @custom_values - @issue.attributes = params[:issue] - if @issue.save - flash[:notice] = l(:notice_successful_update) - redirect_to :action => 'show', :id => @issue - end - end - end - - def change_status - @history = @issue.histories.build(params[:history]) + def show + @status_options = @issue.status.workflows.find(:all, :include => :new_status, :conditions => ["role_id=? and tracker_id=?", self.logged_in_user.role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if self.logged_in_user + @custom_values = @issue.custom_values.find(:all, :include => :custom_field) + end + + def edit + @priorities = Enumeration::get_values('IPRI') + if request.get? + @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) } + else + begin + # Retrieve custom fields and values + @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]) } + @issue.custom_values = @custom_values + @issue.attributes = params[:issue] + if @issue.save + flash[:notice] = l(:notice_successful_update) + redirect_to :action => 'show', :id => @issue + end + rescue ActiveRecord::StaleObjectError + # Optimistic locking exception + flash[:notice] = l(:notice_locking_conflict) + end + end + end + + def change_status + @history = @issue.histories.build(params[:history]) @status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", self.logged_in_user.role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if self.logged_in_user - - if params[:confirm] - @history.author_id = self.logged_in_user.id if self.logged_in_user - - if @history.save - @issue.status = @history.status - @issue.fixed_version_id = (params[:issue][:fixed_version_id]) - @issue.assigned_to_id = (params[:issue][:assigned_to_id]) - if @issue.save - flash[:notice] = l(:notice_successful_update) - Mailer.deliver_issue_change_status(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled? - redirect_to :action => 'show', :id => @issue - end - end - end + if params[:confirm] + begin + @history.author_id = self.logged_in_user.id if self.logged_in_user + @issue.status = @history.status + @issue.fixed_version_id = (params[:issue][:fixed_version_id]) + @issue.assigned_to_id = (params[:issue][:assigned_to_id]) + @issue.lock_version = (params[:issue][:lock_version]) + if @issue.save + flash[:notice] = l(:notice_successful_update) + Mailer.deliver_issue_change_status(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled? + redirect_to :action => 'show', :id => @issue + end + rescue ActiveRecord::StaleObjectError + # Optimistic locking exception + flash[:notice] = l(:notice_locking_conflict) + end + end @assignable_to = @project.members.find(:all, :include => :user).collect{ |m| m.user } - - end - - def destroy - @issue.destroy - redirect_to :controller => 'projects', :action => 'list_issues', :id => @project - end - + end + + def destroy + @issue.destroy + redirect_to :controller => 'projects', :action => 'list_issues', :id => @project + end + def add_attachment # Save the attachment if params[:attachment][:file].size > 0 @@ -94,7 +99,7 @@ class IssuesController < ApplicationController private def find_project - @issue = Issue.find(params[:id]) + @issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category]) @project = @issue.project end end diff --git a/redmine/app/views/issues/change_status.rhtml b/redmine/app/views/issues/change_status.rhtml index 9c14bdb88..e525de60d 100644 --- a/redmine/app/views/issues/change_status.rhtml +++ b/redmine/app/views/issues/change_status.rhtml @@ -24,6 +24,7 @@

<%= text_area 'history', 'notes', :cols => 60, :rows => 10 %>

- + +<%= hidden_field 'issue', 'lock_version' %> <%= submit_tag l(:button_save) %> <%= end_form_tag %> diff --git a/redmine/app/views/issues/edit.rhtml b/redmine/app/views/issues/edit.rhtml index 5a118f893..13f9e4399 100644 --- a/redmine/app/views/issues/edit.rhtml +++ b/redmine/app/views/issues/edit.rhtml @@ -21,6 +21,6 @@

- +<%= f.hidden_field :lock_version %> <%= submit_tag l(:button_save) %> <% end %> \ No newline at end of file diff --git a/redmine/app/views/issues/show.rhtml b/redmine/app/views/issues/show.rhtml index acba6af0c..fc48e47a1 100644 --- a/redmine/app/views/issues/show.rhtml +++ b/redmine/app/views/issues/show.rhtml @@ -49,7 +49,7 @@

<%=l(:label_history)%>

-<% for history in @issue.histories.find(:all, :include => :author) %> +<% for history in @issue.histories.find(:all, :include => [:author, :status]) %> diff --git a/redmine/db/migrate/001_setup.rb b/redmine/db/migrate/001_setup.rb index 65fd23422..00d788bec 100644 --- a/redmine/db/migrate/001_setup.rb +++ b/redmine/db/migrate/001_setup.rb @@ -120,7 +120,8 @@ class Setup < ActiveRecord::Migration t.column "assigned_to_id", :integer t.column "priority_id", :integer, :default => 0, :null => false t.column "fixed_version_id", :integer - t.column "author_id", :integer, :default => 0, :null => false + t.column "author_id", :integer, :default => 0, :null => false + t.column "lock_version", :integer, :default => 0, :null => false t.column "created_on", :timestamp t.column "updated_on", :timestamp end diff --git a/redmine/lang/de.yml b/redmine/lang/de.yml index cdfffabde..7fcecca94 100644 --- a/redmine/lang/de.yml +++ b/redmine/lang/de.yml @@ -58,6 +58,7 @@ notice_successful_update: Erfolgreiches Update. notice_successful_delete: Erfolgreiche Auslassung. notice_successful_connection: Erfolgreicher Anschluß. notice_file_not_found: Erbetene Akte besteht nicht oder ist gelöscht worden. +notice_locking_conflict: Data have been updated by another user. gui_validation_error: 1 Störung gui_validation_error_plural: %d Störungen diff --git a/redmine/lang/en.yml b/redmine/lang/en.yml index 7fd806362..780d06c34 100644 --- a/redmine/lang/en.yml +++ b/redmine/lang/en.yml @@ -58,6 +58,7 @@ notice_successful_update: Successful update. notice_successful_delete: Successful deletion. notice_successful_connection: Successful connection. notice_file_not_found: Requested file doesn't exist or has been deleted. +notice_locking_conflict: Data have been updated by another user. gui_validation_error: 1 error gui_validation_error_plural: %d errors diff --git a/redmine/lang/es.yml b/redmine/lang/es.yml index a9806b3e3..85d78d31e 100644 --- a/redmine/lang/es.yml +++ b/redmine/lang/es.yml @@ -58,6 +58,7 @@ notice_successful_update: Successful update. notice_successful_delete: Successful deletion. notice_successful_connection: Successful connection. notice_file_not_found: Requested file doesn't exist or has been deleted. +notice_locking_conflict: Data have been updated by another user. gui_validation_error: 1 error gui_validation_error_plural: %d errores diff --git a/redmine/lang/fr.yml b/redmine/lang/fr.yml index 5c2936801..a321b7dae 100644 --- a/redmine/lang/fr.yml +++ b/redmine/lang/fr.yml @@ -58,6 +58,7 @@ notice_successful_update: Mise à jour effectuée avec succès. notice_successful_delete: Suppression effectuée avec succès. notice_successful_connection: Connection réussie. notice_file_not_found: Le fichier demandé n'existe pas ou a été supprimé. +notice_locking_conflict: Les données ont été mises à jour par un autre utilisateur. Mise à jour impossible. gui_validation_error: 1 erreur gui_validation_error_plural: %d erreurs
<%= format_date(history.created_on) %> <%= history.author.display_name %>