form_configurable.rb 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. module FormConfigurable
  2. extend ActiveSupport::Concern
  3. included do
  4. class_attribute :_form_configurable_fields
  5. self._form_configurable_fields = HashWithIndifferentAccess.new { |h, k| h[k] = [] }
  6. end
  7. delegate :form_configurable_attributes, to: :class
  8. delegate :form_configurable_fields, to: :class
  9. def is_form_configurable?
  10. true
  11. end
  12. def validate_option(method)
  13. if self.respond_to? "validate_#{method}".to_sym
  14. self.send("validate_#{method}".to_sym)
  15. else
  16. false
  17. end
  18. end
  19. def complete_option(method)
  20. if self.respond_to? "complete_#{method}".to_sym
  21. self.send("complete_#{method}".to_sym)
  22. end
  23. end
  24. module ClassMethods
  25. def form_configurable(name, *args)
  26. options = args.extract_options!.reverse_merge(roles: [], type: :string)
  27. if args.all?(Symbol)
  28. options.assert_valid_keys([:type, :roles, :values, :ace, :cache_response, :html_options])
  29. end
  30. if options[:type] == :array && (options[:values].blank? || !options[:values].is_a?(Array))
  31. raise ArgumentError.new('When using :array as :type you need to provide the :values as an Array')
  32. end
  33. if options[:roles].is_a?(Symbol)
  34. options[:roles] = [options[:roles]]
  35. end
  36. case options[:type]
  37. when :array
  38. options[:roles] << :completable
  39. class_eval <<-EOF, __FILE__, __LINE__ + 1
  40. def complete_#{name}
  41. #{options[:values]}.map { |v| {text: v, id: v} }
  42. end
  43. EOF
  44. when :json
  45. class_eval <<-EOF, __FILE__, __LINE__ + 1
  46. before_validation :decode_#{name}_json
  47. private def decode_#{name}_json
  48. case value = options[:#{name}]
  49. when String
  50. options[:#{name}] =
  51. begin
  52. JSON.parse(value)
  53. rescue StandardError
  54. value
  55. end
  56. end
  57. end
  58. EOF
  59. end
  60. _form_configurable_fields[name] = options
  61. end
  62. def form_configurable_fields
  63. self._form_configurable_fields
  64. end
  65. def form_configurable_attributes
  66. form_configurable_fields.keys
  67. end
  68. end
  69. end