From 0785250023624357b3419e462b745fd934f11314 Mon Sep 17 00:00:00 2001 From: Daniel Lobato Date: Tue, 15 Sep 2015 11:51:40 +0200 Subject: [PATCH] Fixes #7230, #12021 - Upgrade to Rails 4.1.5 This commits upgrades Rails to Rails 4.1.5. See a description of the changes included here, and go to the pull request in GitHub to see more detailed explanations: * Update gems to a Rails 4 compatible version, including dependencies * Fix counter cache columns * Remove conditions, order, limit from has_many relations * Remove test runner On minitest 5, the runner API was deprecated, so our custom test runner is no longer working. * Remove useless add_index on lookup_values match An index is added previously on lookup_values :priority, and on Rails 4 rename_column changes 'priority' to 'match' already changes the name of the index. * Alias assert_include to assert_includes. * Expire topbar cache * Subclass ApplicationMailer in test to avoid 'missing template' error * Fixes #12021 - Use .to_param to find parent object in LookupKeys controller On Rails 4, .find will not default to .friendly.find so find_hostgroup, find_environment and find_host will fail for non numeric IDs. However, we can use from_param to find these objects. This is something we can do both on Rails 3 and Rails 4, whereas using .friendly isn't an option until friendly_id 5.0, which depends on Rails 4. * Use explicit friendly ID search. * find_common finder uses from_param -> friendly -> find The finder needed to be refactored because with the new Friendly ID we have to use .friendly explicitely. It currently follows the strategy of searching like this: - from_param -> .friendly -> regular find * Remove RecordNotFound errors from parameterizable in rails 4 * Protect attributes using attr_accessible and protected_attributes * url_for doesn't append port when protocol is specified Some of our tests are checking if port 80 or 443 is included in the URL generated by lib/foreman/renderer.rb. However url_for has changed in Rails 4 and now it does not append the port even if explicitly added. If the protocol is specified, as it is in this case, then the url generated will just have the protocol (http or https) but not the port (80 or 443) * Validate object instead of _id column in join tables On Rails 4 such validations will fail when we try to create objects without explicitely assigning the id. Puppetclass.new(:config_group => config_group) would fail even for a valid config group, :config_group_id => config_group.id should be used instead. To avoid that, we validate the object, not the ID column * Rails 4 non backwards compatible syntax changes Changes that have to deal with how some of the internal Rails objects need a new syntax, like generating routes, exceptions, form builders. None of these are Rails 3 compatible. * Fixes #12199 - rails 4 migration errors There are actually two parts to the issue of not being able to migrate with this branch. The first is https://gist.github.com/eLobato/0f5db50b5c93cc6c277c and can be temporarily fixed with rails/sass-rails#136 (comment) I am not sure of a long term fix for that atm. Once that is patched, this error https://gist.github.com/johnpmitsch/96e5ba3629890931193a happens on a migration. This will fix that error by changing the Migrator class initializer arguments which have changed from rails 3 to rails 4 * Refactor fact value test to not modify user_roles directly * Return external usergroupsas an array * Use eager_load to preload associations to be used in where Fixes #7230, #12021 - Upgrade to Rails 4.1.5 This commits upgrades Rails to Rails 4.1.5. See a description of the changes included here, and go to the pull request in GitHub to see more detailed explanations: * Update gems to a Rails 4 compatible version, including dependencies * Fix counter cache columns * Remove conditions, order, limit from has_many relations * Remove test runner On minitest 5, the runner API was deprecated, so our custom test runner is no longer working. * Remove useless add_index on lookup_values match An index is added previously on lookup_values :priority, and on Rails 4 rename_column changes 'priority' to 'match' already changes the name of the index. * Alias assert_include to assert_includes. * Expire topbar cache * Subclass ApplicationMailer in test to avoid 'missing template' error * Fixes #12021 - Use .to_param to find parent object in LookupKeys controller On Rails 4, .find will not default to .friendly.find so find_hostgroup, find_environment and find_host will fail for non numeric IDs. However, we can use from_param to find these objects. This is something we can do both on Rails 3 and Rails 4, whereas using .friendly isn't an option until friendly_id 5.0, which depends on Rails 4. * Use explicit friendly ID search. * find_common finder uses from_param -> friendly -> find The finder needed to be refactored because with the new Friendly ID we have to use .friendly explicitely. It currently follows the strategy of searching like this: - from_param -> .friendly -> regular find * Remove RecordNotFound errors from parameterizable in rails 4 * Protect attributes using attr_accessible and protected_attributes * url_for doesn't append port when protocol is specified Some of our tests are checking if port 80 or 443 is included in the URL generated by lib/foreman/renderer.rb. However url_for has changed in Rails 4 and now it does not append the port even if explicitly added. If the protocol is specified, as it is in this case, then the url generated will just have the protocol (http or https) but not the port (80 or 443) * Validate object instead of _id column in join tables On Rails 4 such validations will fail when we try to create objects without explicitely assigning the id. Puppetclass.new(:config_group => config_group) would fail even for a valid config group, :config_group_id => config_group.id should be used instead. To avoid that, we validate the object, not the ID column * Rails 4 non backwards compatible syntax changes Changes that have to deal with how some of the internal Rails objects need a new syntax, like generating routes, exceptions, form builders. None of these are Rails 3 compatible. * Fixes #12199 - rails 4 migration errors There are actually two parts to the issue of not being able to migrate with this branch. The first is https://gist.github.com/eLobato/0f5db50b5c93cc6c277c and can be temporarily fixed with rails/sass-rails#136 (comment) I am not sure of a long term fix for that atm. Once that is patched, this error https://gist.github.com/johnpmitsch/96e5ba3629890931193a happens on a migration. This will fix that error by changing the Migrator class initializer arguments which have changed from rails 3 to rails 4 * Refactor fact value test to not modify user_roles directly * Return external usergroupsas an array * Use eager_load to preload associations to be used in where * Auto detect jenkins rake task in application.rb and set test RAILS_ENV in that case * Reference previously undigested assets in CSS and js as digested using asset-url or image-url * Adapted sprockets manifest.json instead of manifest.yml (ehelms) --- Gemfile | 16 ++-- ...{host_checkbox.js => host_checkbox.js.erb} | 29 +++---- app/assets/javascripts/topbar.js | 2 +- app/assets/stylesheets/application.scss | 20 +++-- app/assets/stylesheets/charts.scss | 4 +- app/controllers/api/v1/reports_controller.rb | 2 +- .../api/v2/config_reports_controller.rb | 4 +- .../api/v2/host_classes_controller.rb | 6 +- app/controllers/api/v2/models_controller.rb | 6 ++ .../api/v2/parameters_controller.rb | 5 +- app/controllers/api/v2/reports_controller.rb | 2 +- app/controllers/application_controller.rb | 2 +- .../api/v2/lookup_keys_common_controller.rb | 59 ++++++--------- app/controllers/concerns/find_common.rb | 16 ++-- app/controllers/config_reports_controller.rb | 2 +- app/controllers/hosts_controller.rb | 6 +- app/controllers/settings_controller.rb | 2 +- app/controllers/unattended_controller.rb | 6 +- app/helpers/application_helper.rb | 8 ++ app/models/bookmark.rb | 2 +- app/models/compute_profile.rb | 1 + app/models/concerns/audit_extensions.rb | 3 +- app/models/concerns/has_many_common.rb | 10 ++- app/models/concerns/host_common.rb | 2 +- app/models/concerns/host_params.rb | 3 +- app/models/concerns/parameterizable.rb | 4 +- app/models/concerns/taxonomix.rb | 14 ++-- app/models/config_group_class.rb | 6 +- app/models/domain.rb | 2 +- app/models/environment.rb | 4 +- app/models/host/base.rb | 10 +-- app/models/host/managed.rb | 13 ++-- app/models/host_class.rb | 1 - app/models/hostgroup_class.rb | 1 - .../lookup_keys/puppetclass_lookup_key.rb | 2 +- app/models/operatingsystem.rb | 1 + app/models/puppetclass.rb | 8 +- app/models/report.rb | 2 +- app/models/subnet.rb | 2 +- app/models/user.rb | 5 +- app/models/user_mail_notification.rb | 2 +- app/models/user_role.rb | 2 +- app/models/usergroup.rb | 10 ++- app/models/usergroup_member.rb | 2 +- app/services/foreman/plugin.rb | 11 ++- app/services/tax_host.rb | 5 +- app/views/api/v2/interfaces/base.json.rabl | 1 + app/views/home/_topbar.html.erb | 2 +- bundler.d/assets.rb | 39 +++++----- bundler.d/console.rb | 3 - bundler.d/test.rb | 8 +- config/application.rb | 12 ++- config/environments/development.rb | 7 -- config/environments/production.rb | 29 ++++--- config/environments/test.rb | 3 + config/initializers/0_maintain_test_schema.rb | 1 + config/initializers/1_fast_gettext.rb | 3 + config/initializers/routing_hash_for.rb | 29 +++++++ ...0444_add_look_up_key_id_to_puppet_class.rb | 1 - .../20140219183343_migrate_permissions.rb | 24 +++--- lib/foreman/logging.rb | 2 + lib/middleware/catch_json_parse_errors.rb | 2 +- lib/tasks/jenkins.rake | 11 +-- lib/tasks/plugin_assets.rake | 75 ++++++++----------- lib/tasks/test.rake | 7 -- .../api/base_controller_subclass_test.rb | 64 +++++++--------- .../smart_class_parameters_controller_test.rb | 2 +- .../api/v2/smart_proxies_controller_test.rb | 2 +- .../provisioning_templates_controller_test.rb | 2 +- test/functional/unattended_controller_test.rb | 4 +- ...custom_runner.rb => custom_runner_test.rb} | 2 + test/test_helper.rb | 6 +- test/test_runner.rb | 35 --------- test/unit/application_mailer_test.rb | 12 ++- test/unit/compute_resource_test.rb | 2 +- test/unit/fact_value_test.rb | 73 +++++++++++------- test/unit/helpers/layout_helper_test.rb | 4 +- test/unit/host_test.rb | 12 ++- 78 files changed, 420 insertions(+), 384 deletions(-) rename app/assets/javascripts/{host_checkbox.js => host_checkbox.js.erb} (84%) create mode 100644 config/initializers/0_maintain_test_schema.rb create mode 100644 config/initializers/routing_hash_for.rb rename test/lib/{custom_runner.rb => custom_runner_test.rb} (74%) delete mode 100644 test/test_runner.rb diff --git a/Gemfile b/Gemfile index 19ceae4ce331..d4a5634a9671 100644 --- a/Gemfile +++ b/Gemfile @@ -4,29 +4,28 @@ require File.expand_path('../lib/regexp_extensions', FOREMAN_GEMFILE) source 'https://rubygems.org' -gem 'rails', '3.2.22' -gem 'rack-cache', '< 1.3.0' +gem 'rails', '4.1.5' gem 'json', '~> 1.5' gem 'rest-client', '~> 1.6.0', :require => 'rest_client' -gem 'audited-activerecord', '3.0.0' +gem 'audited-activerecord', '~> 4.0' gem 'will_paginate', '~> 3.0' gem 'ancestry', '~> 2.0' -gem 'scoped_search', '~> 3.0' +gem 'scoped_search', '>= 3.2.2', '< 4' gem 'ldap_fluff', '>= 0.3.5', '< 1.0' gem 'net-ldap', '>= 0.8.0' -gem 'apipie-rails', '~> 0.2.5' +gem 'apipie-rails', '~> 0.3.4' gem 'rabl', '~> 0.11' gem 'oauth', '~> 0.4' gem 'deep_cloneable', '~> 2.0' gem 'foreigner', '~> 1.4' gem 'validates_lengths_from_database', '~> 0.2' -gem 'friendly_id', '~> 4.0' +gem 'friendly_id', '~> 5.0' gem 'secure_headers', '~> 1.3' gem 'safemode', '~> 1.2' gem 'fast_gettext', '~> 0.8' gem 'gettext_i18n_rails', '~> 1.0' gem 'i18n', '~> 0.6.4' -gem 'rails-i18n', '~> 3.0.0' +gem 'rails-i18n', '~> 4.0.0' gem 'turbolinks', '~> 2.5' gem 'logging', '>= 1.8.0', '< 3.0.0' gem 'fog-core', '1.34.0' @@ -36,6 +35,9 @@ if RUBY_VERSION.start_with? '1.9.' else gem 'net-ssh' end +gem 'activerecord-session_store', '~> 0.1.1' +gem 'rails-observers', '~> 0.1' +gem 'protected_attributes', '~> 1.1.1' Dir["#{File.dirname(FOREMAN_GEMFILE)}/bundler.d/*.rb"].each do |bundle| self.instance_eval(Bundler.read_file(bundle)) diff --git a/app/assets/javascripts/host_checkbox.js b/app/assets/javascripts/host_checkbox.js.erb similarity index 84% rename from app/assets/javascripts/host_checkbox.js rename to app/assets/javascripts/host_checkbox.js.erb index 00ba01c9af27..c1c5a5eb808d 100644 --- a/app/assets/javascripts/host_checkbox.js +++ b/app/assets/javascripts/host_checkbox.js.erb @@ -118,20 +118,21 @@ function submit_modal_form() { function build_modal(element, url) { var url = url + "?" + $.param({host_ids: $.foremanSelectedHosts}); var title = $(element).attr('data-dialog-title'); - $('#confirmation-modal .modal-header h4').text(title); - $('#confirmation-modal .modal-body').empty().append(""); - $('#confirmation-modal').modal(); - $("#confirmation-modal .modal-body").load(url + " #content", - function(response, status, xhr) { - $("#loading").hide(); - $('#submit_multiple').val(''); - var b = $("#confirmation-modal .btn-primary"); - if ($(response).find('#content form select').length > 0) - b.addClass("disabled").attr("disabled", true); - else - b.removeClass("disabled").attr("disabled", false); - }); - return false; + $('#confirmation-modal .modal-header h4').text(title); + $('#confirmation-modal .modal-body').empty() + .append("'"); + $('#confirmation-modal').modal(); + $("#confirmation-modal .modal-body").load(url + " #content", + function(response, status, xhr) { + $("#loading").hide(); + $('#submit_multiple').val(''); + var b = $("#confirmation-modal .btn-primary"); + if ($(response).find('#content form select').length > 0) + b.addClass("disabled").attr("disabled", true); + else + b.removeClass("disabled").attr("disabled", false); + }); + return false; } diff --git a/app/assets/javascripts/topbar.js b/app/assets/javascripts/topbar.js index 4499eb3ad4a0..dc85785638b2 100644 --- a/app/assets/javascripts/topbar.js +++ b/app/assets/javascripts/topbar.js @@ -50,7 +50,7 @@ $(document).on('mouseleave','.loc-submenu', function(){ function mark_active_menu() { var menus = $('.menu_tab_dropdown'), path = window.location.pathname + window.location.search, - link = $("[href='%s'".replace('%s', path)); + link = $("[href='%s']".replace('%s', path)); menus.removeClass('active'); $("[class^='menu_tab_']").removeClass('active'); diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index f49daa103dee..1cbfbaa958bc 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -108,11 +108,11 @@ a.config_group_name { } .editable { - background: url("edit.png") no-repeat scroll 98% 6px transparent; + background: image-url("edit.png") no-repeat scroll 98% 6px transparent; cursor: pointer; padding: 4px 26px 4px 0; &:hover { - background: url("edit-hover.png") no-repeat scroll 98% 6px #F2F2F2; + background: image-url("edit-hover.png") no-repeat scroll 98% 6px #F2F2F2; } } @@ -282,23 +282,23 @@ table { } .sorting { - background: url('sort_both.png') no-repeat center right; + background: image-url('sort_both.png') no-repeat center right; } .sorting_asc { - background: url('sort_asc.png') no-repeat center right; + background: image-url('sort_asc.png') no-repeat center right; } .sorting_desc { - background: url('sort_desc.png') no-repeat center right; + background: image-url('sort_desc.png') no-repeat center right; } .sorting_asc_disabled { - background: url('sort_asc_disabled.png') no-repeat center right; + background: image-url('sort_asc_disabled.png') no-repeat center right; } .sorting_desc_disabled { - background: url('sort_desc_disabled.png') no-repeat center right; + background: image-url('sort_desc_disabled.png') no-repeat center right; } } @@ -340,7 +340,7 @@ table { .spinner-placeholder { width: 16px; height: 16px; - background: url('spinner.gif'); + background: image-url('spinner.gif'); text-indent: 20px; white-space: nowrap; margin: 20% 30% 0 40%; @@ -537,3 +537,7 @@ span.glyphicon.host-status { word-wrap: break-word; /* IE */ word-break: break-all; } + +.ms-container { + background: transparent image-url('switch.png') no-repeat 270px 80px; +} diff --git a/app/assets/stylesheets/charts.scss b/app/assets/stylesheets/charts.scss index bf3877087043..7492a88b1817 100644 --- a/app/assets/stylesheets/charts.scss +++ b/app/assets/stylesheets/charts.scss @@ -122,9 +122,9 @@ } .statistics-pie.small .overlay { - background: url(/assets/pie_overlay.png) no-repeat; + background: image-url('/assets/pie_overlay.png') no-repeat; background-size: cover; - -ms-behavior: url(/assets/background-size.htc); + -ms-behavior: asset-url('/assets/background-size.htc'); z-index: 1; } diff --git a/app/controllers/api/v1/reports_controller.rb b/app/controllers/api/v1/reports_controller.rb index eaa8fa59e201..5165a6a21566 100644 --- a/app/controllers/api/v1/reports_controller.rb +++ b/app/controllers/api/v1/reports_controller.rb @@ -36,7 +36,7 @@ def destroy param :id, :identifier, :required => true def last - conditions = { :host_id => Host.authorized(:view_hosts).find(params[:host_id]).try(:id) } if params[:host_id].present? + conditions = { :host_id => Host.authorized(:view_hosts).friendly.find(params[:host_id]).try(:id) } if params[:host_id].present? max_id = resource_scope.where(conditions).maximum(:id) @report = resource_scope.includes(:logs => [:message, :source]).find(max_id) render :show diff --git a/app/controllers/api/v2/config_reports_controller.rb b/app/controllers/api/v2/config_reports_controller.rb index 46e4c8f7508a..1da7141d6737 100644 --- a/app/controllers/api/v2/config_reports_controller.rb +++ b/app/controllers/api/v2/config_reports_controller.rb @@ -54,7 +54,9 @@ def destroy param :id, :identifier, :required => true def last - conditions = { :host_id => Host.authorized(:view_hosts).find(params[:host_id]).try(:id) } if params[:host_id].present? + if params[:host_id].present? + conditions = { :host_id => resource_finder(Host.authorized(:view_hosts), params[:host_id]).try(:id) } + end max_id = resource_scope.where(conditions).maximum(:id) @config_report = resource_scope.includes(:logs => [:message, :source]).find(max_id) render :show diff --git a/app/controllers/api/v2/host_classes_controller.rb b/app/controllers/api/v2/host_classes_controller.rb index 28c4b82bcad8..ff8dcdf38a11 100644 --- a/app/controllers/api/v2/host_classes_controller.rb +++ b/app/controllers/api/v2/host_classes_controller.rb @@ -35,8 +35,10 @@ def destroy # overwrite resource_name so it's host and and not host_class, since we want to return @host def find_host not_found and return false if params[:host_id].blank? - @host = Host.find(params[:host_id]) if Host::Managed.respond_to?(:authorized) && - Host::Managed.authorized("view_host", Host::Managed) + if Host::Managed.respond_to?(:authorized) && + Host::Managed.authorized("view_host", Host::Managed) + @host = resource_finder(Host.authorized(:view_hosts), params[:host_id]) + end end end end diff --git a/app/controllers/api/v2/models_controller.rb b/app/controllers/api/v2/models_controller.rb index 9554fe389592..1a288ab6e3b4 100644 --- a/app/controllers/api/v2/models_controller.rb +++ b/app/controllers/api/v2/models_controller.rb @@ -47,6 +47,12 @@ def update def destroy process_response @model.destroy end + + private + + def find_resource + @model = Model.friendly.find(params[:id]) || super + end end end end diff --git a/app/controllers/api/v2/parameters_controller.rb b/app/controllers/api/v2/parameters_controller.rb index 0d3f536396b1..fd0ebae7b489 100644 --- a/app/controllers/api/v2/parameters_controller.rb +++ b/app/controllers/api/v2/parameters_controller.rb @@ -165,8 +165,9 @@ def allowed_nested_id def find_parameter # nested_obj is required, so no need to check here @parameters = nested_obj.send(parameters_method) - @parameter = @parameters.find(params[:id]) - return @parameter if @parameter + @parameter = @parameters.from_param(params[:id]) + @parameter ||= @parameters.friendly.find(params[:id]) + return @parameter if @parameter.present? not_found end end diff --git a/app/controllers/api/v2/reports_controller.rb b/app/controllers/api/v2/reports_controller.rb index b432de0b0fde..ca5006c20cb3 100644 --- a/app/controllers/api/v2/reports_controller.rb +++ b/app/controllers/api/v2/reports_controller.rb @@ -54,7 +54,7 @@ def destroy param :id, :identifier, :required => true def last - conditions = { :host_id => Host.authorized(:view_hosts).find(params[:host_id]).try(:id) } if params[:host_id].present? + conditions = { :host_id => resource_finder(Host.authorized(:view_hosts), params[:host_id]).try(:id) } if params[:host_id].present? max_id = resource_scope.where(conditions).maximum(:id) @report = resource_scope.includes(:logs => [:message, :source]).find(max_id) render :show diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 383587134e9a..fddc6e673c94 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -193,7 +193,7 @@ def remote_user_provided? end def display_layout? - return nil if two_pane? + return false if two_pane? "application" end diff --git a/app/controllers/concerns/api/v2/lookup_keys_common_controller.rb b/app/controllers/concerns/api/v2/lookup_keys_common_controller.rb index 009eef9d15ff..5e76e13f01e5 100644 --- a/app/controllers/concerns/api/v2/lookup_keys_common_controller.rb +++ b/app/controllers/concerns/api/v2/lookup_keys_common_controller.rb @@ -19,22 +19,6 @@ module Api::V2::LookupKeysCommonController before_filter :return_if_smart_mismatch, :only => [:show, :update, :destroy] end - def puppetclass_id? - params.keys.include?('puppetclass_id') - end - - def environment_id? - params.keys.include?('environment_id') - end - - def host_id? - params.keys.include?('host_id') - end - - def hostgroup_id? - params.keys.include?('hostgroup_id') - end - def smart_variable_id? params.keys.include?('smart_variable_id') || controller_name.match(/smart_variables/) end @@ -43,28 +27,22 @@ def smart_class_parameter_id? params.keys.include?('smart_class_parameter_id') || controller_name.match(/smart_class_parameters/) end - def find_puppetclass - @puppetclass = Puppetclass.authorized(:view_puppetclasses).find(params['puppetclass_id']) - rescue ActiveRecord::RecordNotFound - not_found({ :error => { :message => (_("Puppet class with id '%{id}' was not found") % { :id => params['puppetclass_id'] }) } }) - end + [Puppetclass, Environment, Host::Base, Hostgroup].each do |model| + model_string = model.to_s.split('::').first.downcase - def find_environment - @environment = Environment.authorized(:view_environments).find(params['environment_id']) - rescue ActiveRecord::RecordNotFound - not_found({ :error => { :message => (_("Environment with id '%{id}' was not found") % { :id => params['environment_id'] }) } }) - end - - def find_host - @host = Host::Base.authorized(:view_hosts).find(params['host_id']) - rescue ActiveRecord::RecordNotFound - not_found({ :error => { :message => (_("Host with id '%{id}' was not found") % { :id => params['host_id'] }) } }) - end + define_method("#{model_string}_id?") do + params.keys.include?("#{model_string}_id") + end - def find_hostgroup - @hostgroup = Hostgroup.authorized(:view_hostgroups).find(params['hostgroup_id']) - rescue ActiveRecord::RecordNotFound - not_found({ :error => { :message => (_("Hostgroup with id '%{id}' was not found") % { :id => params['hostgroup_id'] }) } }) + define_method("find_#{model_string}") do + scope = model.authorized(:"view_#{model_string.pluralize}") + begin + instance_variable_set("@#{model_string}", + resource_finder(scope, params["#{model_string}_id"])) + rescue ActiveRecord::RecordNotFound + model_not_found(model_string) + end + end end def find_smart_variable @@ -144,4 +122,13 @@ def return_if_smart_mismatch not_found "#{obj} not found by id '#{id}'" end end + + private + + def model_not_found(model) + error_message = ( + _("%{model} with id '%{id}' was not found") % + { :id => params["#{model}_id"], :model => model.capitalize } ) + not_found(:error => { :message => error_message } ) + end end diff --git a/app/controllers/concerns/find_common.rb b/app/controllers/concerns/find_common.rb index 5d8a5a30edd9..a037251e7627 100644 --- a/app/controllers/concerns/find_common.rb +++ b/app/controllers/concerns/find_common.rb @@ -1,12 +1,18 @@ -# this mixin is used by both ApplicationController and Api::BaseController -# searches for an object based on its id, name, label, etc and assign it to an instance variable +# This mixin is used by both ApplicationController and Api::BaseController +# Searches for an object based on its id, name, label, etc and assign it to an instance variable # friendly_id performs the logic if params[:id] is 'id' or 'id-name' or 'name' module FindCommon - # example: @host = Host.find(params[:id]) def find_resource - not_found and return if params[:id].blank? - instance_variable_set("@#{resource_name}", resource_scope.find(params[:id])) + instance_variable_set("@#{resource_name}", + resource_finder(resource_scope, params[:id])) + end + + def resource_finder(scope, id) + raise ActiveRecord::RecordNotFound if scope.empty? + result = scope.from_param(id) if scope.respond_to?(:from_param) + result ||= scope.friendly.find(id) if scope.respond_to?(:friendly) + result || scope.find(id) end def resource_name(resource = controller_name) diff --git a/app/controllers/config_reports_controller.rb b/app/controllers/config_reports_controller.rb index 436cf0b9a850..8b404ca971d8 100644 --- a/app/controllers/config_reports_controller.rb +++ b/app/controllers/config_reports_controller.rb @@ -10,7 +10,7 @@ def index def show # are we searching for the last report? if params[:id] == "last" - conditions = { :host_id => Host.authorized(:view_hosts).find(params[:host_id]).try(:id) } if params[:host_id].present? + conditions = { :host_id => resource_finder(Host.authorized(:view_hosts), params[:host_id]).try(:id) } if params[:host_id].present? params[:id] = resource_base.where(conditions).maximum(:id) end diff --git a/app/controllers/hosts_controller.rb b/app/controllers/hosts_controller.rb index aeca21fc36ea..e4e1f07dcca0 100644 --- a/app/controllers/hosts_controller.rb +++ b/app/controllers/hosts_controller.rb @@ -169,7 +169,7 @@ def puppetclass_parameters def externalNodes certname = params[:name] @host ||= resource_base.find_by_certname certname - @host ||= resource_base.find certname + @host ||= resource_base.friendly.find certname not_found and return unless @host begin @@ -352,7 +352,7 @@ def update_multiple_parameters skipped = [] params[:name].each do |name, value| next if value.empty? - if (host_param = host.host_parameters.find(name)) + if (host_param = host.host_parameters.friendly.find(name)) counter += 1 if host_param.update_attribute(:value, value) else skipped << name @@ -698,7 +698,7 @@ def taxonomy_scope # overwrite application_controller def find_resource not_found and return false if (id = params[:id]).blank? - @host = resource_base.find(id) + @host = resource_base.friendly.find(id) @host ||= resource_base.find_by_mac params[:host][:mac] if params[:host] && params[:host][:mac] not_found and return(false) unless @host diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb index ef4133685ef5..57d7bd6686ed 100644 --- a/app/controllers/settings_controller.rb +++ b/app/controllers/settings_controller.rb @@ -13,7 +13,7 @@ def index end def update - @setting = Setting.find(params[:id]) + @setting = Setting.friendly.find(params[:id]) if @setting.parse_string_value(params[:setting][:value]) && @setting.save render :json => @setting else diff --git a/app/controllers/unattended_controller.rb b/app/controllers/unattended_controller.rb index 0678436c17f2..4d14e53198c1 100644 --- a/app/controllers/unattended_controller.rb +++ b/app/controllers/unattended_controller.rb @@ -44,8 +44,8 @@ def built def template return head(:not_found) unless (params.has_key?("id") and params.has_key?(:hostgroup)) - template = ProvisioningTemplate.find(params['id']) - @host = Hostgroup.find(params['hostgroup']) + template = ProvisioningTemplate.find_by_name(params['id']) + @host = Hostgroup.find_by_name(params['hostgroup']) return head(:not_found) unless template and @host @@ -107,7 +107,7 @@ def get_host_details def find_host_by_spoof host = Nic::Base.primary.find_by_ip(params.delete('spoof')).try(:host) if params['spoof'].present? - host ||= Host.find(params.delete('hostname')) if params['hostname'].present? + host ||= Host.find_by_name(params.delete('hostname')) if params['hostname'].present? @spoof = host.present? host end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index b29f756a73d2..887d3fb1d8f6 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -32,6 +32,14 @@ def link_to(*args, &block) end end + def link_to_function(name, function, html_options = {}) + onclick_tag = "#{html_options[:onclick]}; " if html_options[:onclick] + onclick = "#{onclick_tag}#{function}; return false;" + href = html_options[:href] || '#' + + content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick)) + end + protected def contract(model) diff --git a/app/models/bookmark.rb b/app/models/bookmark.rb index ffed9d221d6c..1cccd037abde 100644 --- a/app/models/bookmark.rb +++ b/app/models/bookmark.rb @@ -7,7 +7,7 @@ class Bookmark < ActiveRecord::Base validates_lengths_from_database belongs_to :owner, :polymorphic => true - attr_accessible :name, :controller, :query, :public + attr_accessible :name, :query, :public, :controller audited :allow_mass_assignment => true validates :name, :uniqueness => {:scope => :controller}, :unless => Proc.new{|b| Bookmark.my_bookmarks.where(:name => b.name).empty?} diff --git a/app/models/compute_profile.rb b/app/models/compute_profile.rb index d30cc211f1ee..20864e463d8d 100644 --- a/app/models/compute_profile.rb +++ b/app/models/compute_profile.rb @@ -6,6 +6,7 @@ class ComputeProfile < ActiveRecord::Base validates_lengths_from_database attr_accessible :name + audited has_associated_audits diff --git a/app/models/concerns/audit_extensions.rb b/app/models/concerns/audit_extensions.rb index a1ec3226f7ab..aef24f0a0232 100644 --- a/app/models/concerns/audit_extensions.rb +++ b/app/models/concerns/audit_extensions.rb @@ -5,7 +5,8 @@ module AuditExtensions included do belongs_to :user, :class_name => 'User' belongs_to :search_users, :class_name => 'User', :foreign_key => :user_id - belongs_to :search_hosts, :class_name => 'Host', :foreign_key => :auditable_id, :conditions => { :audits => { :auditable_type => 'Host' } } + belongs_to :search_hosts, -> { where(:audits => { :auditable_type => 'Host' }) }, + :class_name => 'Host', :foreign_key => :auditable_id belongs_to :search_hostgroups, :class_name => 'Hostgroup', :foreign_key => :auditable_id belongs_to :search_parameters, :class_name => 'Parameter', :foreign_key => :auditable_id belongs_to :search_templates, :class_name => 'ProvisioningTemplate', :foreign_key => :auditable_id diff --git a/app/models/concerns/has_many_common.rb b/app/models/concerns/has_many_common.rb index 9b013d829cb3..2fc55e62907e 100644 --- a/app/models/concerns/has_many_common.rb +++ b/app/models/concerns/has_many_common.rb @@ -41,8 +41,9 @@ class << self; self end end #### has_many #### - def has_many(association, options = {}) - has_many_names_for(association, options) + def has_many(*args) + options = args.last.is_a?(Hash) ? args.last : {} + has_many_names_for(args.first, options) super end @@ -69,8 +70,9 @@ def has_many_names_for(association, options) end #### belongs_to #### - def belongs_to(association, options = {}) - belongs_to_name_for(association, options) + def belongs_to(*args) + options = args.last.is_a?(Hash) ? args.last : {} + belongs_to_name_for(args.first, options) super end diff --git a/app/models/concerns/host_common.rb b/app/models/concerns/host_common.rb index 69d9b606ec5a..c7fadfeb5851 100644 --- a/app/models/concerns/host_common.rb +++ b/app/models/concerns/host_common.rb @@ -209,7 +209,7 @@ def individual_puppetclasses end def available_puppetclasses - return Puppetclass.where(nil) if environment_id.blank? + return Puppetclass.where(nil) if environment.blank? environment.puppetclasses - parent_classes end diff --git a/app/models/concerns/host_params.rb b/app/models/concerns/host_params.rb index ff3f685bea2d..37c0afedab40 100644 --- a/app/models/concerns/host_params.rb +++ b/app/models/concerns/host_params.rb @@ -7,6 +7,7 @@ module HostParams accepts_nested_attributes_for :host_parameters, :allow_destroy => true include ParameterValidators attr_reader :cached_host_params + attr_accessible :host_parameters_attributes def params host_params.update(lookup_keys_params) @@ -58,7 +59,7 @@ def host_inherited_params_objects def host_params_objects # Host parameters should always be first for the uniq order - (host_parameters + host_inherited_params_objects.reverse!).uniq {|param| param.name} + (host_parameters + host_inherited_params_objects.to_a.reverse!).uniq {|param| param.name} end end end diff --git a/app/models/concerns/parameterizable.rb b/app/models/concerns/parameterizable.rb index 4a0c63e36487..0fb27066e476 100644 --- a/app/models/concerns/parameterizable.rb +++ b/app/models/concerns/parameterizable.rb @@ -12,7 +12,7 @@ def to_param end def self.from_param(id) - self.find(id.to_i) + self.find_by_id(id.to_i) end end end @@ -27,7 +27,7 @@ def to_param end def self.from_param(id_name) - self.find(id_name.to_i) + self.find_by_id(id_name.to_i) end end end diff --git a/app/models/concerns/taxonomix.rb b/app/models/concerns/taxonomix.rb index 45019c254cd2..75f116a14c67 100644 --- a/app/models/concerns/taxonomix.rb +++ b/app/models/concerns/taxonomix.rb @@ -3,12 +3,14 @@ module Taxonomix include DirtyAssociations included do - taxonomy_join_table = "taxable_taxonomies" - has_many taxonomy_join_table, :dependent => :destroy, :as => :taxable - has_many :locations, :through => taxonomy_join_table, :source => :taxonomy, - :conditions => "taxonomies.type='Location'", :validate => false - has_many :organizations, :through => taxonomy_join_table, :source => :taxonomy, - :conditions => "taxonomies.type='Organization'", :validate => false + taxonomy_join_table = :taxable_taxonomies + has_many taxonomy_join_table.to_sym, :dependent => :destroy, :as => :taxable + has_many :locations, -> { where(:type => 'Location') }, + :through => taxonomy_join_table, :source => :taxonomy, + :validate => false + has_many :organizations, -> { where(:type => 'Organization') }, + :through => taxonomy_join_table, :source => :taxonomy, + :validate => false after_initialize :set_current_taxonomy scoped_search :in => :locations, :on => :name, :rename => :location, :complete_value => true diff --git a/app/models/config_group_class.rb b/app/models/config_group_class.rb index 904d58fd4a4f..2e22eb5f9b37 100644 --- a/app/models/config_group_class.rb +++ b/app/models/config_group_class.rb @@ -9,7 +9,7 @@ class ConfigGroupClass < ActiveRecord::Base belongs_to :puppetclass belongs_to :config_group, :counter_cache => true - validates :puppetclass_id, :presence => true - validates :config_group_id, :presence => true, - :uniqueness => {:scope => :puppetclass_id} + validates :puppetclass, :presence => true + validates :config_group, :presence => true, + :uniqueness => {:scope => :puppetclass} end diff --git a/app/models/domain.rb b/app/models/domain.rb index be367e0c178c..2ea9fa2cb0ef 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -21,7 +21,7 @@ class Domain < ActiveRecord::Base has_many :domain_parameters, :dependent => :destroy, :foreign_key => :reference_id, :inverse_of => :domain has_many :parameters, :dependent => :destroy, :foreign_key => :reference_id, :class_name => "DomainParameter" has_many :interfaces, :class_name => 'Nic::Base' - has_many :primary_interfaces, :class_name => 'Nic::Base', :conditions => { :primary => true } + has_many :primary_interfaces, -> { where(:primary => true) }, :class_name => 'Nic::Base' has_many :hosts, :through => :interfaces has_many :primary_hosts, :through => :primary_interfaces, :source => :host diff --git a/app/models/environment.rb b/app/models/environment.rb index fdf3007b88af..045abe5c05a7 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -11,12 +11,12 @@ class Environment < ActiveRecord::Base before_destroy EnsureNotUsedBy.new(:hosts, :hostgroups) has_many :environment_classes, :dependent => :destroy - has_many :puppetclasses, :through => :environment_classes, :uniq => true + has_many :puppetclasses, -> { uniq }, :through => :environment_classes has_many_hosts has_many :hostgroups - has_many :trends, :as => :trendable, :class_name => "ForemanTrend" validates :name, :uniqueness => true, :presence => true, :alphanumeric => true + has_many :trends, :as => :trendable, :class_name => "ForemanTrend" has_many :template_combinations, :dependent => :destroy has_many :provisioning_templates, :through => :template_combinations diff --git a/app/models/host/base.rb b/app/models/host/base.rb index 41d3c1a2d8df..9b41c504f9fd 100644 --- a/app/models/host/base.rb +++ b/app/models/host/base.rb @@ -39,12 +39,10 @@ class Base < ActiveRecord::Base belongs_to :model, :counter_cache => :hosts_count has_many :fact_values, :dependent => :destroy, :foreign_key => :host_id has_many :fact_names, :through => :fact_values - has_many :interfaces, :dependent => :destroy, :inverse_of => :host, :class_name => 'Nic::Base', - :foreign_key => :host_id, :order => 'identifier' - has_one :primary_interface, :class_name => 'Nic::Base', :foreign_key => 'host_id', - :conditions => { :primary => true } - has_one :provision_interface, :class_name => 'Nic::Base', :foreign_key => 'host_id', - :conditions => { :provision => true } + has_many :interfaces, -> { order(:identifier) }, :dependent => :destroy, :inverse_of => :host, :class_name => 'Nic::Base', + :foreign_key => :host_id + has_one :primary_interface, -> { where(:primary => true) }, :class_name => 'Nic::Base', :foreign_key => 'host_id' + has_one :provision_interface, -> { where(:provision => true) }, :class_name => 'Nic::Base', :foreign_key => 'host_id' has_one :domain, :through => :primary_interface has_one :subnet, :through => :primary_interface accepts_nested_attributes_for :interfaces, :allow_destroy => true diff --git a/app/models/host/managed.rb b/app/models/host/managed.rb index 4e7969496ba6..d16c36e844be 100644 --- a/app/models/host/managed.rb +++ b/app/models/host/managed.rb @@ -12,10 +12,8 @@ class Host::Managed < Host::Base belongs_to :owner, :polymorphic => true belongs_to :compute_resource belongs_to :image - has_many :host_statuses, :class_name => 'HostStatus::Status', :foreign_key => 'host_id', :inverse_of => :host, - :dependent => :destroy + has_many :host_statuses, :class_name => 'HostStatus::Status', :foreign_key => 'host_id', :inverse_of => :host, :dependent => :destroy has_one :configuration_status_object, :class_name => 'HostStatus::ConfigurationStatus', :foreign_key => 'host_id' - has_one :token, :foreign_key => :host_id, :dependent => :destroy before_destroy :remove_reports @@ -155,7 +153,8 @@ class Jail < ::Safemode::Jail audited :except => [:last_report, :puppet_status, :last_compile, :lookup_value_matcher], :allow_mass_assignment => true has_associated_audits #redefine audits relation because of the type change (by default the relation will look for auditable_type = 'Host::Managed') - has_many :audits, :foreign_key => :auditable_id, :class_name => Audited.audit_class.name, :conditions => { :auditable_type => 'Host' } + has_many :audits, -> { where(:auditable_type => 'Host') }, :foreign_key => :auditable_id, + :class_name => Audited.audit_class.name # some shortcuts alias_attribute :os, :operatingsystem @@ -589,7 +588,7 @@ def apply_inherited_attributes(attributes, initialized = true) new_hostgroup = self.hostgroup if initialized unless [new_hostgroup.try(:id), new_hostgroup.try(:friendly_id)].include? new_hostgroup_id - new_hostgroup = Hostgroup.find(new_hostgroup_id) + new_hostgroup = Hostgroup.friendly.find(new_hostgroup_id) end return attributes unless new_hostgroup @@ -814,11 +813,11 @@ def available_template_kinds(provisioning = nil) cr = ComputeResource.find_by_id(self.compute_resource_id) images = cr.try(:images) if images.blank? - [TemplateKind.find('finish')] + [TemplateKind.friendly.find('finish')] else uuid = self.compute_attributes[cr.image_param_name] image_kind = images.find_by_uuid(uuid).try(:user_data) ? 'user_data' : 'finish' - [TemplateKind.find(image_kind)] + [TemplateKind.friendly.find(image_kind)] end else TemplateKind.all diff --git a/app/models/host_class.rb b/app/models/host_class.rb index e1d078b94c25..e6f8953dcf6c 100644 --- a/app/models/host_class.rb +++ b/app/models/host_class.rb @@ -7,7 +7,6 @@ class HostClass < ActiveRecord::Base belongs_to_host belongs_to :puppetclass - validates :host, :presence => true validates :puppetclass_id, :presence => true, :uniqueness => {:scope => :host_id} def name diff --git a/app/models/hostgroup_class.rb b/app/models/hostgroup_class.rb index 26efa1074b53..ca1203a5f7d6 100644 --- a/app/models/hostgroup_class.rb +++ b/app/models/hostgroup_class.rb @@ -8,7 +8,6 @@ class HostgroupClass < ActiveRecord::Base belongs_to :puppetclass, :counter_cache => :hostgroups_count attr_accessible :hostgroup_id, :hostgroup, :puppetclass_id, :puppetclass - validates :hostgroup, :presence => true validates :puppetclass_id, :presence => true, :uniqueness => {:scope => :hostgroup_id} diff --git a/app/models/lookup_keys/puppetclass_lookup_key.rb b/app/models/lookup_keys/puppetclass_lookup_key.rb index ffb1f8ead157..6cfd122e8a46 100644 --- a/app/models/lookup_keys/puppetclass_lookup_key.rb +++ b/app/models/lookup_keys/puppetclass_lookup_key.rb @@ -1,6 +1,6 @@ class PuppetclassLookupKey < LookupKey has_many :environment_classes, :dependent => :destroy - has_many :environments, :through => :environment_classes, :uniq => true + has_many :environments, -> { uniq }, :through => :environment_classes has_many :param_classes, :through => :environment_classes, :source => :puppetclass scoped_search :in => :param_classes, :on => :name, :rename => :puppetclass, :complete_value => true diff --git a/app/models/operatingsystem.rb b/app/models/operatingsystem.rb index 3678045511b3..382521033e5c 100644 --- a/app/models/operatingsystem.rb +++ b/app/models/operatingsystem.rb @@ -34,6 +34,7 @@ class Operatingsystem < ActiveRecord::Base accepts_nested_attributes_for :os_parameters, :allow_destroy => true include ParameterValidators has_many :trends, :as => :trendable, :class_name => "ForemanTrend" + attr_name :to_label validates :minor, :numericality => {:greater_than_or_equal_to => 0}, :allow_nil => true, :allow_blank => true validates :name, :presence => true, :no_whitespace => true, diff --git a/app/models/puppetclass.rb b/app/models/puppetclass.rb index cc4fbe0d1869..7a5f9cc5fa56 100644 --- a/app/models/puppetclass.rb +++ b/app/models/puppetclass.rb @@ -8,7 +8,7 @@ class Puppetclass < ActiveRecord::Base validates_lengths_from_database before_destroy EnsureNotUsedBy.new(:hosts, :hostgroups) has_many :environment_classes, :dependent => :destroy - has_many :environments, :through => :environment_classes, :uniq => true + has_many :environments, -> { uniq }, :through => :environment_classes has_and_belongs_to_many :operatingsystems has_many :hostgroup_classes has_many :hostgroups, :through => :hostgroup_classes, :dependent => :destroy @@ -19,8 +19,8 @@ class Puppetclass < ActiveRecord::Base has_many :lookup_keys, :inverse_of => :puppetclass, :dependent => :destroy, :class_name => 'VariableLookupKey' accepts_nested_attributes_for :lookup_keys, :reject_if => ->(a) { a[:key].blank? }, :allow_destroy => true # param classes - has_many :class_params, :through => :environment_classes, :uniq => true, - :source => :puppetclass_lookup_key, :conditions => 'environment_classes.puppetclass_lookup_key_id is NOT NULL' + has_many :class_params, -> { where('environment_classes.puppetclass_lookup_key_id is NOT NULL').uniq }, + :through => :environment_classes, :source => :puppetclass_lookup_key accepts_nested_attributes_for :class_params, :reject_if => ->(a) { a[:key].blank? }, :allow_destroy => true validates :name, :uniqueness => true, :presence => true, :no_whitespace => true @@ -202,7 +202,7 @@ def self.prepare_rdoc(root) def self.search_by_host(key, operator, value) conditions = sanitize_sql_for_conditions(["hosts.name #{operator} ?", value_to_sql(operator, value)]) - direct = Puppetclass.joins(:hosts).where(conditions).uniq.pluck('puppetclasses.id') + direct = Puppetclass.joins(:hosts).where(conditions).pluck('puppetclasses.id').uniq hostgroup = Hostgroup.joins(:hosts).where(conditions).first indirect = hostgroup.blank? ? [] : HostgroupClass.where(:hostgroup_id => hostgroup.path_ids).uniq.pluck('puppetclass_id') return { :conditions => "1=0" } if direct.blank? && indirect.blank? diff --git a/app/models/report.rb b/app/models/report.rb index 806fe34a073c..9d5b7484b344 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -31,7 +31,7 @@ class Report < ActiveRecord::Base # returns reports for hosts in the User's filter set scope :my_reports, lambda { if !User.current.admin? || Organization.expand(Organization.current).present? || Location.expand(Location.current).present? - joins_authorized(Host, :view_hosts, :where => Host.taxonomy_conditions) + joins_authorized(Host, :view_hosts) end } diff --git a/app/models/subnet.rb b/app/models/subnet.rb index 735ba11cedd8..9b5d709e0160 100644 --- a/app/models/subnet.rb +++ b/app/models/subnet.rb @@ -23,7 +23,7 @@ class Subnet < ActiveRecord::Base has_many :subnet_domains, :dependent => :destroy has_many :domains, :through => :subnet_domains has_many :interfaces, :class_name => 'Nic::Base' - has_many :primary_interfaces, :class_name => 'Nic::Base', :conditions => { :primary => true } + has_many :primary_interfaces, -> { where(:primary => true) }, :class_name => 'Nic::Base' has_many :hosts, :through => :interfaces has_many :primary_hosts, :through => :primary_interfaces, :source => :host validates :network, :mask, :name, :presence => true diff --git a/app/models/user.rb b/app/models/user.rb index 29e2616d055e..ebc5af10c90b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -25,10 +25,10 @@ class User < ActiveRecord::Base has_many :auditable_changes, :class_name => '::Audit', :as => :user has_many :direct_hosts, :class_name => 'Host', :as => :owner has_many :usergroup_member, :dependent => :destroy, :as => :member - has_many :user_roles, :dependent => :destroy, :foreign_key => 'owner_id', :conditions => {:owner_type => self.to_s} + has_many :user_roles, -> { where(:owner_type => 'User') }, :dependent => :destroy, :foreign_key => 'owner_id' has_many :cached_user_roles, :dependent => :destroy has_many :cached_usergroups, :through => :cached_usergroup_members, :source => :usergroup - has_many :cached_roles, :through => :cached_user_roles, :source => :role, :uniq => true + has_many :cached_roles, -> { uniq }, :through => :cached_user_roles, :source => :role has_many :usergroups, :through => :usergroup_member, :dependent => :destroy has_many :roles, :through => :user_roles, :dependent => :destroy has_many :filters, :through => :cached_roles @@ -393,6 +393,7 @@ def self.random_password(size = 16) end def expire_topbar_cache(sweeper) + return if sweeper.controller.nil? sweeper.expire_fragment(TopbarSweeper.fragment_name(id)) end diff --git a/app/models/user_mail_notification.rb b/app/models/user_mail_notification.rb index b3869fb43d19..041b2122e34c 100644 --- a/app/models/user_mail_notification.rb +++ b/app/models/user_mail_notification.rb @@ -4,7 +4,7 @@ class UserMailNotification < ActiveRecord::Base belongs_to :user belongs_to :mail_notification - validates :user_id, :presence => true + validates :user, :presence => true validates :mail_notification, :presence => true scope :daily, -> { where(:interval => 'Daily') } diff --git a/app/models/user_role.rb b/app/models/user_role.rb index 5478a528c40d..b49180c46ebd 100644 --- a/app/models/user_role.rb +++ b/app/models/user_role.rb @@ -59,7 +59,7 @@ def cache_user_roles! end def build_user_role_cache - [ self.cached_user_roles.build(:user => owner, :role => role) ] + [ self.cached_user_roles.build(:user_id => owner.id, :role_id => role.id) ] end def build_user_group_role_cache(owner) diff --git a/app/models/usergroup.rb b/app/models/usergroup.rb index 1570670d78ba..c255fd15f203 100644 --- a/app/models/usergroup.rb +++ b/app/models/usergroup.rb @@ -11,7 +11,7 @@ class Usergroup < ActiveRecord::Base validates_lengths_from_database before_destroy EnsureNotUsedBy.new(:hosts), :ensure_last_admin_group_is_not_deleted - has_many :user_roles, :dependent => :destroy, :foreign_key => 'owner_id', :conditions => {:owner_type => self.to_s} + has_many :user_roles, -> { where(:owner_type => 'Usergroup') }, :dependent => :destroy, :foreign_key => 'owner_id' has_many :roles, :through => :user_roles, :dependent => :destroy has_many :usergroup_members, :dependent => :destroy @@ -19,12 +19,14 @@ class Usergroup < ActiveRecord::Base has_many :usergroups, :through => :usergroup_members, :source => :member, :source_type => 'Usergroup', :dependent => :destroy has_many :external_usergroups, :dependent => :destroy, :inverse_of => :usergroup - has_many :cached_usergroup_members - has_many :usergroup_parents, :dependent => :destroy, :foreign_key => 'member_id', - :conditions => "member_type = 'Usergroup'", :class_name => 'UsergroupMember' + has_many :cached_usergroups, :through => :cached_usergroup_members, :source => :usergroup + has_many :cached_usergroup_members, :foreign_key => 'usergroup_id' + has_many :usergroup_parents, -> { where("member_type = 'Usergroup'") }, :dependent => :destroy, + :foreign_key => 'member_id', :class_name => 'UsergroupMember' has_many :parents, :through => :usergroup_parents, :source => :usergroup, :dependent => :destroy has_many_hosts :as => :owner + validates :name, :uniqueness => true, :presence => true # The text item to see in a select dropdown menu diff --git a/app/models/usergroup_member.rb b/app/models/usergroup_member.rb index e27c25c99dd5..781bf438f35d 100644 --- a/app/models/usergroup_member.rb +++ b/app/models/usergroup_member.rb @@ -100,7 +100,7 @@ def find_all_user_roles end def find_all_user_roles_for(usergroup) - usergroup.user_roles + usergroup.parents.map { |g| find_all_user_roles_for(g) } + (UserRole.where(:owner => usergroup )+ usergroup.parents.map { |g| find_all_user_roles_for(g) }).flatten end def find_all_usergroups diff --git a/app/services/foreman/plugin.rb b/app/services/foreman/plugin.rb index 0899b1fc33fe..853a57b45158 100644 --- a/app/services/foreman/plugin.rb +++ b/app/services/foreman/plugin.rb @@ -176,6 +176,9 @@ def delete_menu_item(menu, item) end def tests_to_skip(hash) + Rails.logger.warn "Minitest 5 deprecated the runner API and plugin tests \ +can't be skipped right now. Future versions of Foreman might bring back this \ +feature" # Format is { "testclass" => [ "skip1", "skip2" ] } hash.each do |testclass,tests| if self.class.tests_to_skip[testclass].nil? @@ -219,8 +222,12 @@ def role(name, permissions) end def pending_migrations - migrations = ActiveRecord::Migrator.new(:up, ActiveRecord::Migrator.migrations_paths).pending_migrations - migrations.size > 0 + migration_paths = ActiveRecord::Migrator.migrations( + ActiveRecord::Migrator.migrations_paths) + pending_migrations = ActiveRecord::Migrator.new(:up, migration_paths). + pending_migrations + + pending_migrations.size > 0 end # List of helper methods allowed for templates in safe mode diff --git a/app/services/tax_host.rb b/app/services/tax_host.rb index 010b40d03726..11c8a1ec17f7 100644 --- a/app/services/tax_host.rb +++ b/app/services/tax_host.rb @@ -154,8 +154,9 @@ def non_inherited_ids(v1 = self.selected_ids, v2 = self.inherited_ids) # populate used_ids for 3 non-standard_id's def user_ids(hosts = self.hosts) - #TODO: when migrating to rails 3.1+ switch to inner select on users. - User.unscoped.joins(:direct_hosts).where({ :hosts => { :id => hosts }, :users => { :admin => false } }).pluck('DISTINCT users.id') + User.unscoped.except_admin. + eager_load(:direct_hosts).where(:hosts => { :id => hosts.map(&:id) }). + pluck('DISTINCT users.id') end def provisioning_template_ids(hosts = self.hosts) diff --git a/app/views/api/v2/interfaces/base.json.rabl b/app/views/api/v2/interfaces/base.json.rabl index 43dcaf324f2c..2181267775cf 100644 --- a/app/views/api/v2/interfaces/base.json.rabl +++ b/app/views/api/v2/interfaces/base.json.rabl @@ -2,5 +2,6 @@ object @interface attributes :id, :name, :ip, :mac, :identifier, :primary, :provision node :type do |i| + next if i.is_a? Symbol i.class.humanized_name.downcase end diff --git a/app/views/home/_topbar.html.erb b/app/views/home/_topbar.html.erb index 416e39876889..51df69aa9809 100644 --- a/app/views/home/_topbar.html.erb +++ b/app/views/home/_topbar.html.erb @@ -33,7 +33,7 @@
<% if User.current %> - <% cache(TopbarSweeper.fragment_name) do %> + <% cache(TopbarSweeper.fragment_name, :skip_digest => true) do %>