controller_issues_bulk_edit_before_save => how to make as controller_issues_bulk_edit_after_save
Added by Stéphane CHÂTEAU over 2 years ago
For a plugin, I create geometries to be able to georeference issues.
The goal of my problem is to be able to copy these geometries when creating issues. It's done by hooking controller_issues_new_after_save like this:
module xPointeHook module Hooks class GeometryIssueHook < Redmine::Hook::Listener def controller_issues_new_after_save_geometries(context = { }) issue = context[:issue] if !issue.id.nil? && !issue.project_id.nil? if context[:params].key?(:copy_from) && !context[:params][:copy_from].nil? project = Project.find(issue.project_id) if !project.nil? #Rails.logger.info("project = " + project.id.to_s + " / name = " + project.name) #Rails.logger.info("issue source = " + context[:params][:copy_from].to_s) if is_project_allow_pointe?(project) # Uniquement si le projet destination autorise les pointés Pointes.where(issue_id: context[:params][:copy_from]).all.each do |blc_pointe| pointe = Pointes.new( { :issue_id => issue.id, :pointe => blc_pointe.pointe.nil? ? nil : blc_pointe.pointe.as_text(), :point_attendu => blc_pointe.point_attendu.nil? ? nil : blc_pointe.point_attendu.as_text(), :line_attendu => blc_pointe.line_attendu.nil? ? nil : blc_pointe.line_attendu.as_text(), :polygon_attendu => blc_pointe.polygon_attendu.nil? ? nil : blc_pointe.polygon_attendu.as_text(), :state => blc_pointe.state, :comment => blc_pointe.comment } ) pointe.save end end end end end return '' end alias_method :controller_issues_new_after_save, :controller_issues_new_after_save_geometries end end end
First I hook controller_issues_new_after_save and then, if the issue is a copy, and have geometries allowed on target project (is_project_allow_pointe?) then I copied Pointes'rows that match to source Issue to new one.
It's work perfectly !
The problem is ... for bulk copy. There are controller_issues_bulk_edit_before_save but no controller_issues_bulk_edit_after_save like asked by some developpers: https://www.redmine.org/issues/8757
I'm neebie on rails.
My question is: is it possible to hook controller_issues_bulk_edit_before_save and then hook on each issue 'after_save' callback with ActiveRecord?
The problem is, I cannot create Pointes.new if I have not the issue id and in controller_issues_bulk_edit_before_save the row is not already saved and the id is nil, so I must wait the issue really saved into database.
May be it's a way to be able to add Pointes rows after issue bulk copy.
Actually I have this code: (same as previous but the specific hook controller_issues_bulk_edit_before_save.
module xPointeHook module Hooks class GeometryIssueHook < Redmine::Hook::Listener def controller_issues_bulk_edit_before_save_geometries(context = { }) if context[:params][:copy].present? # Uniquement en cas de copie issue = context[:issue] Rails.logger.info("issue.id = " + (issue.id.nil? ? "nil" : issue.id.to_s)) Rails.logger.info("issue.project_id = " + (issue.project_id.nil? ? "nil" : issue.project_id.to_s)) context[:params].each do |key, value| Rails.logger.info("params[#{key}] = #{value}") end end Rails.logger.info(">>>>>>>> issue = #{context[:issue]}") end alias_method :controller_issues_bulk_edit_before_save, :controller_issues_bulk_edit_before_save_geometries end end end
It's seems that in params[:ids] there is a list of source ids that allow me to retrieve source issue and then source Pointes rows.
Replies (1)
RE: controller_issues_bulk_edit_before_save => how to make as controller_issues_bulk_edit_after_save - Added by Stéphane CHÂTEAU over 2 years ago
It's done by another way:
Controller:
module xPointeHook module Hooks class GeometryIssueHook < Redmine::Hook::Listener def controller_issues_new_before_save_geometries(context = { }) issue = context[:issue] if !issue.project_id.nil? if context[:params].key?(:copy_from) && !context[:params][:copy_from].nil? && context[:params].key?(:copy_geometries) && context[:params][:copy_geometries] != "0" project = Project.find(issue.project_id) if !project.nil? && is_project_allow_pointe?(project) # Uniquement si le projet destination autorise les pointés issue.set_create_pointe_on_save_issue_id_source(context[:params][:copy_from]) end end end return '' end def controller_issues_bulk_edit_before_save_geometries(context = { }) if context[:params][:copy].present? && context[:issue].copy? && context[:params].key?(:copy_geometries) && context[:params][:copy_geometries] != "0" context[:issue].set_create_pointe_on_save_issue_id_source(context[:issue].copy_id) else if !check_pointes_states(context) context[:issue].set_not_allowed_to_be_saved end end end alias_method :controller_issues_new_before_save, :controller_issues_new_before_save_geometries alias_method :controller_issues_bulk_edit_before_save, :controller_issues_bulk_edit_before_save_geometries end end end
Patch Issue:
module Geometry::Patches::Models module IssuePatch def self.included(base) base.send :include, InstanceMethods end module InstanceMethods def set_not_allowed_to_be_saved @can_save = false end def set_create_pointe_on_save_issue_id_source(id) @issue_id_ref = id end # Est appelé à chaque fois qu'une FT est sauvée def save bRet = false if @can_save.nil? || @can_save if !@issue_id_ref.nil? # Sauvegarde autorisée mais copie des pointés Issue.transaction do bRet = super if bRet bRet = create_pointe_copy_from if !bRet # S'il faut copier les pointés et que ça a échoué raise ActiveRecord::Rollback end end end else # Traitement par défaut de toutes les sauvegarde d'issue bRet = super end else # Sera remis à false à la prochaine tentative @can_save = nil @issue_id_ref = nil bRet = false end bRet end # Returns the issue copy id def copy_id return copy? ? @copied_from : nil end private # Est appelé à chaque fois qu'une FT est sauvée def create_pointe_copy_from bRet = true if !@issue_id_ref.nil? issueid = @issue_id_ref @issue_id_ref = nil Pointes.where(issue_id: issueid).all.each do |blc_pointe| pointe = Pointes.new( { :issue_id => self.id, :pointe => blc_pointe.pointe.nil? ? nil : blc_pointe.pointe.as_text(), :point_attendu => blc_pointe.point_attendu.nil? ? nil : blc_pointe.point_attendu.as_text(), :line_attendu => blc_pointe.line_attendu.nil? ? nil : blc_pointe.line_attendu.as_text(), :polygon_attendu => blc_pointe.polygon_attendu.nil? ? nil : blc_pointe.polygon_attendu.as_text(), :state => blc_pointe.state, :comment => blc_pointe.comment } ) bRet = pointe.save && bRet end end bRet end end # Module InstanceMethods end # Module IssuePatch end # Module Geometry
Init.rb: (simplified)
require 'redmine' # It requires the file in lib/geometry/hooks/geometry_issue_hook.rb require_dependency 'geometry/hooks/geometry_issue_hook' Redmine::Plugin.register :geometry do name '' author '' description 'xxx' version '2.0.0' url '' # include file lib/geometry/patches/models/issue_patch.rb file unless Issue.included_modules.include?(Geometry::Patches::Models::IssuePatch) Issue.send(:include, Geometry::Patches::Models::IssuePatch) end end