Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BZ 1238179 - VM Utilization screen generating charts throws internal server error after Rails 4 #3394

2 changes: 1 addition & 1 deletion app/models/rbac.rb
Expand Up @@ -445,7 +445,7 @@ def self.search(options = {})
def self.method_with_scope(ar_scope, options)
if ar_scope == VmdbDatabaseConnection
ar_scope.all
elsif ar_scope < ActsAsArModel
elsif ar_scope < ActsAsArModel || (ar_scope.respond_to?(:instances_are_derived?) && ar_scope.instances_are_derived?)
ar_scope.find(:all, options)
else
ar_scope.apply_legacy_finder_options(options)
Expand Down
34 changes: 34 additions & 0 deletions lib/extensions/ar_merge_conditions.rb
Expand Up @@ -31,9 +31,43 @@ def self.apply_legacy_finder_options(options)
unknown_keys = options.keys - LEGACY_FINDER_METHODS.map(&:first)
raise "Unsupported options #{unknown_keys}" unless unknown_keys.empty?

# Determine whether any of the included associations are polymorphic
has_polymorphic = included_associations(options[:include]).any? { |name| self.reflection_is_polymorphic?(name) }

LEGACY_FINDER_METHODS.inject(all) { |scope, (key, method)|
# Don't call references method on scope if polymorphic associations are
# included to avoid ActiveRecord::EagerLoadPolymorphicError
next(scope) if method == :references && has_polymorphic
#
options[key] ? scope.send(method, options[key]) : scope
}
end

def self.reflection_is_polymorphic?(name)
reflection = _reflect_on_association(name)
reflection ? reflection.polymorphic? : false
end

def self.included_associations(includes)
arr = []
_included_associations includes, arr
arr
end

def self._included_associations(includes, arr)
case includes
when Symbol, String
arr << includes.to_sym
when Array
includes.each do |assoc|
_included_associations assoc, arr
end
when Hash
includes.each do |k, v|
cache = arr << k
_included_associations v, cache
end
end
end
end
end
47 changes: 47 additions & 0 deletions spec/lib/extensions/ar_merge_conditions_spec.rb
@@ -0,0 +1,47 @@
require "spec_helper"

describe ActiveRecord::Base do
context "calling apply_legacy_finder_options" do
before(:each) do
@vm = FactoryGirl.create(:vm_vmware)
@perf = FactoryGirl.create(
:metric_rollup_vm_daily,
:resource_id => @vm.id,
:timestamp => "2010-04-14T00:00:00Z",
:time_profile => @time_profile
)

# Typical includes for rendering daily metrics charts
@include = {
:max_derived_cpu_available => {},
:max_derived_cpu_reserved => {},
:min_cpu_usagemhz_rate_average => {},
:max_cpu_usagemhz_rate_average => {},
:min_cpu_usage_rate_average => {},
:max_cpu_usage_rate_average => {},
:v_pct_cpu_ready_delta_summation => {},
:v_pct_cpu_wait_delta_summation => {},
:v_pct_cpu_used_delta_summation => {},
:max_derived_memory_available => {},
:max_derived_memory_reserved => {},
:min_derived_memory_used => {},
:max_derived_memory_used => {},
:min_disk_usage_rate_average => {},
:max_disk_usage_rate_average => {},
:min_net_usage_rate_average => {},
:max_net_usage_rate_average => {},
:v_derived_storage_used => {},
:resource => {}

}
end
it "should not raise an error when a polymorphic reflection is included" do
result = nil
expect do
result = MetricRollup.apply_legacy_finder_options(:include => @include).to_a
end.not_to raise_error

result.length.should == 1
end
end
end
22 changes: 22 additions & 0 deletions spec/models/metric_rollup_spec.rb
@@ -0,0 +1,22 @@
require "spec_helper"

describe MetricRollup do
context "test" do
it "should not raise an error when a polymorphic reflection is included and references are specified in a query" do
pending "until ActiveRecord is fixed"
# TODO: A fix in ActiveRecord will make this test pass
expect do
MetricRollup.where(:id => 1)
.includes(:resource => {}, :time_profile => {})
.references(:time_profile => {}).last
end.not_to raise_error

# TODO: Also, there is a bug that exists in only the manageiq repo and not rails
# TODO: that causes the error "ActiveRecord::ConfigurationError: nil"
# TODO: instead of the expected "ActiveRecord::EagerLoadPolymorphicError" error.
expect do
Tagging.includes(:taggable => {}).where('bogus_table.column = 1').references(:bogus_table => {}).to_a
end.to raise_error ActiveRecord::EagerLoadPolymorphicError
end
end
end