Project

General

Profile

« Previous | Next » 

Revision c791f6c7

Added by Ondřej Ezr over 1 year ago

Fixes #29939 - drop category column from settings

Settings table was holding category column to support old style of
settings, but it is now ready to be decomissioned as plugins were given
enough time.

View differences:

app/models/setting.rb
require 'resolv'
class Setting < ApplicationRecord
audited :except => [:name, :category]
audited :except => [:name]
extend FriendlyId
friendly_id :name
include ActiveModel::Validations
include EncryptValue
include PermissionName
self.inheritance_column = 'category'
TYPES = %w{integer boolean hash array string}
NONZERO_ATTRS = %w{puppet_interval idle_timeout entries_per_page outofsync_interval}
......
after_save :refresh_registry_value
default_scope -> { order(:name) }
# Filer out settings from disabled plugins
scope :disabled_plugins, -> { where(:category => %w[Setting].concat(descendants.map(&:to_s))) unless Rails.env.development? }
scope :order_by, ->(attr) { except(:order).order(attr) }
scoped_search :on => :id, :complete_enabled => false, :only_explicit => true, :validator => ScopedSearch::Validators::INTEGER
......
'settings.yaml'
end
def self.live_descendants
disabled_plugins.order_by(:name)
end
# can't use our own settings
def self.per_page
20
end
def self.humanized_category
nil
end
def self.[](name)
Foreman.settings[name]
end
......
'see https://github.com/theforeman/foreman/blob/develop/developer_docs/how_to_create_a_plugin.asciidoc#settings for details')
default_settings.each do |s|
t = Setting.setting_type_from_value(s[:default]) || 'string'
kwargs = s.except(:name).merge(type: t.to_sym, category: name, context: :deprecated)
kwargs = s.except(:name).merge(type: t.to_sym, category: name.delete_prefix('Setting::'), context: :deprecated)
Foreman.settings._add(s[:name], **kwargs)
end
true
app/presenters/setting_presenter.rb
# ----- UI helpers ------
def category_label
Foreman::SettingManager.categories[category] || category.safe_constantize&.humanized_category || category_name
Foreman::SettingManager.categories[category] || category_name
end
def category_name
category.delete_prefix('Setting::')
category
end
def select_values
app/services/setting_registry.rb
end
end
def known_categories
unless @known_descendants == Setting.descendants
@known_descendants = Setting.descendants
@known_categories = @known_descendants.map(&:name) << 'Setting'
@values_loaded_at = nil # force all values to be reloaded
end
@known_categories
end
def load_values(ignore_cache: false)
# we are loading only known STIs as we load settings fairly early the first time and plugin classes might not be loaded yet.
settings = Setting.unscoped.where(category: known_categories)
settings = Setting.unscoped
settings = settings.where('updated_at >= ?', @values_loaded_at) unless ignore_cache || @values_loaded_at.nil?
settings.each do |s|
unless (definition = find(s.name))
......
end
def _new_db_record(definition)
Setting.new(name: definition.name,
value: definition.value,
category: definition.category.safe_constantize&.name || 'Setting')
Setting.new(name: definition.name, value: definition.value)
end
end
db/migrate/20221126232030_remove_category_from_settings.rb
class RemoveCategoryFromSettings < ActiveRecord::Migration[6.1]
def change
remove_index :settings, :category
remove_column :settings, :category, :string
end
end
test/controllers/settings_controller_test.rb
get :index, session: set_session_user
assert_match /id='valid'/, @response.body
end
test "does not render an old sti type setting" do
assert setting = Setting.create(:name => "foo")
setting.send(:write_attribute, :category, "Setting::Invalid")
get :index, session: set_session_user
assert_no_match /id='Invalid'/, @response.body
end
end
test/factories/settings.rb
FactoryBot.define do
factory :setting do
category { 'Setting' }
sequence(:name) { |n| "setting#{n}" }
sequence(:name) { |n| "setting#{n}" }
end
end
test/fixtures/settings.yml
---
attributes66:
name: delivery_method
category: Setting
value: :test
attribute97:
name: ct_command
category: Setting
value: "['/usr/bin/cat']"
attribute98:
name: fcct_command
category: Setting
value: "['/usr/bin/cat']"
test/models/setting_test.rb
assert !setting.save
end
test 'orders settings alphabetically' do
a_name = 'a_foo'
b_name = 'b_foo'
c_name = 'c_foo'
FactoryBot.create(:setting, :name => b_name, :value => 'whatever')
FactoryBot.create(:setting, :name => a_name, :value => 'whatever')
FactoryBot.create(:setting, :name => c_name, :value => 'whatever')
settings = Setting.live_descendants.select(&:name)
a_foo = settings.index { |item| item.name == a_name }
b_foo = settings.index { |item| item.name == b_name }
c_foo = settings.index { |item| item.name == c_name }
assert a_foo
assert b_foo
assert c_foo
assert a_foo < b_foo
assert b_foo < c_foo
end
test "should update login page footer text with multiple valid long values" do
setting = Setting.create(name: 'login_text')
RFauxFactory.gen_strings(1000).values.each do |value|
setting.value = value
assert setting.valid?, "Can't update discovery_prefix setting with valid value #{value}"
assert setting.valid?, "Can't update login_text setting with valid value #{value}"
end
end
end
test/unit/setting_registry_test.rb
let(:default) { 5 }
let(:setting_value) { nil }
let(:setting_memo) { {} }
let(:setting) { Setting.create(name: 'foo', category: 'Setting') }
let(:setting) { Setting.create(name: 'foo') }
setup do
registry._add('foo', type: :integer, category: 'Setting', default: default, full_name: 'test foo', description: 'test foo', context: :test)

Also available in: Unified diff