Redmine 入门四——Redmine 历史状态查询 Redmine 历史状态的查询使用插件 redmine_status_history 进行状态历史数据的转存和查询。 redmine_status_history 插件提供了历史时间段和两种状态进行可以作为查询条件。使用过程中遇到两个问题:一、不能进行跨项目进行查询;二、新增加查询页面没有和问题查询器进行集成。 为了更方便使用,在 redmine_status_history 插件基础上进行了简单的修改。 1. 修改 init.rb [code] require 'redmine_status_history/patches/query_patch' 对 query 进行补充 #require 'redmine_status_history/hooks/view_issues_index_bottom'[/code] 屏蔽插件新增的查询页面,默认在项目问题列表的下面,非常不方便使用 2. 新增 lib/redmine_status_history/patches/query_patch.rb
[code] require_dependency 'query'
module RedmineStatusHistory module Patches module QueryPatch
def self.included(base) base.send(:include, InstanceMethods) base.class_eval do unloadable alias_method_chain :available_filters, :redmine_status_history alias_method_chain :sql_for_field, :redmine_status_history end
end
module InstanceMethods
def available_filters_with_redmine_status_history return @available_filters if @available_filters available_filters_without_redmine_status_history add_available_filter "status_history_id", :name=>"历史状态",:type => :list_status, :values => IssueStatus.sorted.collect{|s| [s.name, s.id.to_s] } return @available_filters end
def sql_for_field_with_redmine_status_history(field, operator, value, db_table, db_field, is_custom_filter=false) case field when "status_history_id" sql = "#{Issue.table_name}.id IN (SELECT DISTINCT issue_id FROM issue_status_histories WHERE ("+sql_for_history(field, operator, value, IssueStatusHistory.table_name, "status_id")+"))" #Rails.logger.info sql return sql else return sql_for_field_without_redmine_status_history(field, operator, value, db_table, db_field, is_custom_filter) end end
private def sql_for_history(field, operator, value, db_table, db_field, is_custom_filter=false) sql = '' case operator when "=" if value.any? case type_for(field) when :date, :date_past sql = date_clause(db_table, db_field, parse_date(value.first), parse_date(value.first), is_custom_filter) when :integer if is_custom_filter sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) = #{value.first.to_i})" else sql = "#{db_table}.#{db_field} = #{value.first.to_i}" end when :float if is_custom_filter sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) BETWEEN #{value.first.to_f - 1e-5} AND #{value.first.to_f + 1e-5})" else sql = "#{db_table}.#{db_field} BETWEEN #{value.first.to_f - 1e-5} AND #{value.first.to_f + 1e-5}" end else sql = "#{db_table}.#{db_field} IN (" + value.collect{|val| "'#{self.class.connection.quote_string(val)}'"}.join(",") + ")" end else # IN an empty set sql = "1=0" end when "!" if value.any? sql = "(#{db_table}.#{db_field} IS NULL OR #{db_table}.#{db_field} NOT IN (" + value.collect{|val| "'#{self.class.connection.quote_string(val)}'"}.join(",") + "))" else # NOT IN an empty set sql = "1=1" end when "*" sql = "#{db_table}.#{db_field} IS NOT NULL" sql << " AND #{db_table}.#{db_field} <> ''" if is_custom_filter when "o" sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{self.class.connection.quoted_false})" if field == "status_history_id" when "c" sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{self.class.connection.quoted_true})" if field == "status_history_id" else raise "Unknown query operator #{operator}" end
return sql end
end
end end end
unless Query.included_modules.include?(RedmineStatusHistory::Patches::QueryPatch) Query.send(:include, RedmineStatusHistory::Patches::QueryPatch) End [/code]