settings.rb 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. module RailsSettings
  2. class Settings < ActiveRecord::Base
  3. self.table_name = table_name_prefix + 'settings'
  4. class SettingNotFound < RuntimeError; end
  5. belongs_to :thing, polymorphic: true
  6. # get the value field, YAML decoded
  7. def value
  8. YAML.load(self[:value]) if self[:value].present?
  9. end
  10. # set the value field, YAML encoded
  11. def value=(new_value)
  12. self[:value] = new_value.to_yaml
  13. end
  14. class << self
  15. # get or set a variable with the variable as the called method
  16. # rubocop:disable Style/MethodMissing
  17. def method_missing(method, *args)
  18. method_name = method.to_s
  19. super(method, *args)
  20. rescue NoMethodError
  21. # set a value for a variable
  22. if method_name[-1] == '='
  23. var_name = method_name.sub('=', '')
  24. value = args.first
  25. self[var_name] = value
  26. else
  27. # retrieve a value
  28. self[method_name]
  29. end
  30. end
  31. # destroy the specified settings record
  32. def destroy(var_name)
  33. var_name = var_name.to_s
  34. obj = object(var_name)
  35. raise SettingNotFound, "Setting variable \"#{var_name}\" not found" if obj.nil?
  36. obj.destroy
  37. true
  38. end
  39. # retrieve all settings as a hash (optionally starting with a given namespace)
  40. def get_all(starting_with = nil)
  41. vars = thing_scoped.select('var, value')
  42. vars = vars.where("var LIKE '#{starting_with}%'") if starting_with
  43. result = {}
  44. vars.each { |record| result[record.var] = record.value }
  45. result.reverse_merge!(default_settings(starting_with))
  46. result.with_indifferent_access
  47. end
  48. def where(sql = nil)
  49. vars = thing_scoped.where(sql) if sql
  50. vars
  51. end
  52. # get a setting value by [] notation
  53. def [](var_name)
  54. val = object(var_name)
  55. return val.value if val
  56. return Default[var_name] if Default.enabled?
  57. end
  58. # set a setting value by [] notation
  59. def []=(var_name, value)
  60. var_name = var_name.to_s
  61. record = object(var_name) || thing_scoped.new(var: var_name)
  62. record.value = value
  63. record.save!
  64. value
  65. end
  66. def merge!(var_name, hash_value)
  67. raise ArgumentError unless hash_value.is_a?(Hash)
  68. old_value = self[var_name] || {}
  69. raise TypeError, "Existing value is not a hash, can't merge!" unless old_value.is_a?(Hash)
  70. new_value = old_value.merge(hash_value)
  71. self[var_name] = new_value if new_value != old_value
  72. new_value
  73. end
  74. def object(var_name)
  75. return nil unless rails_initialized?
  76. return nil unless table_exists?
  77. thing_scoped.where(var: var_name.to_s).first
  78. end
  79. def thing_scoped
  80. unscoped.where('thing_type is NULL and thing_id is NULL')
  81. end
  82. def source(filename)
  83. Default.source(filename)
  84. end
  85. def rails_initialized?
  86. Rails.application && Rails.application.initialized?
  87. end
  88. private
  89. def default_settings(starting_with = nil)
  90. return {} unless Default.enabled?
  91. return Default.instance if starting_with.nil?
  92. Default.instance.select { |key, _| key.to_s.start_with?(starting_with) }
  93. end
  94. end
  95. end
  96. end