Fixed: queries with multiple custom fields return no result.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@668 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Jean-Philippe Lang 2007-08-26 12:29:53 +00:00
parent 452a20a69a
commit 8da5bad295
6 changed files with 82 additions and 18 deletions

View File

@ -45,7 +45,7 @@ class FeedsController < ApplicationController
end
Issue.with_scope(:find => @find_options) do
@issues = Issue.find :all, :include => [:project, :author, :tracker, :status, :custom_values],
@issues = Issue.find :all, :include => [:project, :author, :tracker, :status],
:order => "#{Issue.table_name}.created_on DESC"
end
@title = (@project ? @project.name : Setting.app_title) + ": " + (query ? query.name : l(:label_reported_issues))
@ -65,7 +65,7 @@ class FeedsController < ApplicationController
end
Journal.with_scope(:find => @find_options) do
@journals = Journal.find :all, :include => [ :details, :user, {:issue => [:project, :author, :tracker, :status, :custom_values]} ],
@journals = Journal.find :all, :include => [ :details, :user, {:issue => [:project, :author, :tracker, :status]} ],
:order => "#{Journal.table_name}.created_on DESC"
end

View File

@ -290,10 +290,10 @@ class ProjectsController < ApplicationController
end
if @query.valid?
@issue_count = Issue.count(:include => [:status, :project, :custom_values], :conditions => @query.statement)
@issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
@issue_pages = Paginator.new self, @issue_count, @results_per_page, params['page']
@issues = Issue.find :all, :order => sort_clause,
:include => [ :assigned_to, :status, :tracker, :project, :priority, :custom_values ],
:include => [ :assigned_to, :status, :tracker, :project, :priority ],
:conditions => @query.statement,
:limit => @issue_pages.items_per_page,
:offset => @issue_pages.current.offset
@ -369,7 +369,7 @@ class ProjectsController < ApplicationController
render :action => 'list_issues' and return unless @query.valid?
@issues = Issue.find :all, :order => sort_clause,
:include => [ :author, :status, :tracker, :priority, :project, :custom_values ],
:include => [ :author, :status, :tracker, :priority, :project ],
:conditions => @query.statement,
:limit => Setting.issues_export_limit.to_i

View File

@ -164,7 +164,8 @@ class Query < ActiveRecord::Base
end
def statement
sql = "1=1"
# project/subprojects clause
clause = ''
if has_filter?("subproject_id")
subproject_ids = []
if operator_for("subproject_id") == "="
@ -172,27 +173,29 @@ class Query < ActiveRecord::Base
else
subproject_ids = project.active_children.collect{|p| p.id}
end
sql << " AND #{Issue.table_name}.project_id IN (%d,%s)" % [project.id, subproject_ids.join(",")] if project
clause << "#{Issue.table_name}.project_id IN (%d,%s)" % [project.id, subproject_ids.join(",")] if project
else
sql << " AND #{Issue.table_name}.project_id=%d" % project.id if project
clause << "#{Issue.table_name}.project_id=%d" % project.id if project
end
# filters clauses
filters_clauses = []
filters.each_key do |field|
next if field == "subproject_id"
v = values_for(field).clone
next unless v and !v.empty?
sql = sql + " AND " unless sql.empty?
sql << "("
sql = ''
if field =~ /^cf_(\d+)$/
# custom field
db_table = CustomValue.table_name
db_field = "value"
sql << "#{db_table}.custom_field_id = #{$1} AND "
db_field = 'value'
sql << "#{Issue.table_name}.id IN (SELECT #{db_table}.customized_id FROM #{db_table} where #{db_table}.customized_type='Issue' AND #{db_table}.customized_id=#{Issue.table_name}.id AND #{db_table}.custom_field_id=#{$1} AND "
else
# regular field
db_table = Issue.table_name
db_field = field
sql << '('
end
# "me" value subsitution
@ -232,9 +235,11 @@ class Query < ActiveRecord::Base
when "!~"
sql = sql + "#{db_table}.#{db_field} NOT LIKE '%#{connection.quote_string(v.first)}%'"
end
sql << ")"
sql << ')'
filters_clauses << sql
end if filters and valid?
sql
clause << (' AND ' + filters_clauses.join(' AND ')) unless filters_clauses.empty?
clause
end
end

View File

@ -34,10 +34,16 @@ custom_values_004:
custom_field_id: 2
customized_id: 1
id: 7
value: "101"
value: "125"
custom_values_005:
customized_type: Issue
custom_field_id: 2
customized_id: 2
id: 8
value: ""
custom_values_008:
customized_type: Issue
custom_field_id: 1
customized_id: 3
id: 11
value: "MySQL"

22
test/fixtures/queries.yml vendored Normal file
View File

@ -0,0 +1,22 @@
---
queries_001:
name: Multiple custom fields query
project_id: 1
filters: |
---
cf_1:
:values:
- MySQL
:operator: "="
status_id:
:values:
- "1"
:operator: o
cf_2:
:values:
- "125"
:operator: "="
id: 1
is_public: true
user_id: 1

31
test/unit/query_test.rb Normal file
View File

@ -0,0 +1,31 @@
# redMine - project management software
# Copyright (C) 2006-2007 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require File.dirname(__FILE__) + '/../test_helper'
class QueryTest < Test::Unit::TestCase
fixtures :projects, :users, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :queries
def test_query_with_multiple_custom_fields
query = Query.find(1)
assert query.valid?
assert query.statement.include?("custom_values.value IN ('MySQL')")
issues = Issue.find :all,:include => [ :assigned_to, :status, :tracker, :project, :priority ], :conditions => query.statement
assert_equal 1, issues.length
assert_equal Issue.find(3), issues.first
end
end