Guest User

Untitled

a guest
May 25th, 2018
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.56 KB | None | 0 0
  1. # lib/multi_parameter_attributes.rb
  2.  
  3. module MultiParameterAttributes
  4. def attributes=(attrs)
  5. multi_parameter_attributes = []
  6. attrs.each do |name, value|
  7. return if attrs.blank?
  8. if name.to_s.include?("(")
  9. multi_parameter_attributes << [ name, value ]
  10. else
  11. writer_method = "#{name}="
  12. if respond_to?(writer_method)
  13. self.send(writer_method, value)
  14. else
  15. self[name.to_s] = value
  16. end
  17. end
  18. end
  19.  
  20. assign_multiparameter_attributes(multi_parameter_attributes)
  21. end
  22.  
  23. def assign_multiparameter_attributes(pairs)
  24. execute_callstack_for_multiparameter_attributes(
  25. extract_callstack_for_multiparameter_attributes(pairs)
  26. )
  27. end
  28.  
  29. def execute_callstack_for_multiparameter_attributes(callstack)
  30. callstack.each do |name, values_with_empty_parameters|
  31. # in order to allow a date to be set without a year, we must keep the empty values.
  32. # Otherwise, we wouldn't be able to distinguish it from a date with an empty day.
  33. values = values_with_empty_parameters.reject(&:nil?)
  34.  
  35. if values.any?
  36. key = self.class.keys[name]
  37. raise ArgumentError, "Unknown key #{name}" if key.nil?
  38. klass = key.type
  39.  
  40. value = if Time == klass
  41. Time.zone.local(*values)
  42. elsif Date == klass
  43. begin
  44. values = values_with_empty_parameters.collect do |v| v.nil? ? 1 : v end
  45. Date.new(*values)
  46. rescue ArgumentError => ex # if Date.new raises an exception on an invalid date
  47. Time.zone.local(*values).to_date # we instantiate Time object and convert it back to a date thus using Time's logic in handling invalid dates
  48. end
  49. else
  50. klass.new(*values)
  51. end
  52. writer_method = "#{name}="
  53. if respond_to?(writer_method)
  54. self.send(writer_method, value)
  55. else
  56. self[name.to_s] = value
  57. end
  58. end
  59. end
  60. end
  61.  
  62. def extract_callstack_for_multiparameter_attributes(pairs)
  63. attributes = { }
  64.  
  65. for pair in pairs
  66. multiparameter_name, value = pair
  67. attribute_name = multiparameter_name.split("(").first
  68. attributes[attribute_name] = [] unless attributes.include?(attribute_name)
  69.  
  70. attributes[attribute_name] << [ find_parameter_position(multiparameter_name), value ]
  71. end
  72.  
  73. attributes.each { |name, values| attributes[name] = values.sort_by{ |v| v.first }.collect { |v| v.last } }
  74. end
  75.  
  76. def find_parameter_position(multiparameter_name)
  77. multiparameter_name.scan(/\(([0-9]*).*\)/).first.first
  78. end
  79.  
  80. end
Add Comment
Please, Sign In to add comment