menu_item_update_action.rb 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. class KnowledgeBase
  2. class MenuItemUpdateAction
  3. def initialize(kb_locale, location, menu_items_data)
  4. @kb_locale = kb_locale
  5. @location = location
  6. @menu_items_data = menu_items_data
  7. end
  8. def scope
  9. @kb_locale.menu_items.location(@location)
  10. end
  11. def perform!
  12. raise_unprocessable if !all_ids_present?
  13. KnowledgeBase::MenuItem.transaction do
  14. KnowledgeBase::MenuItem.acts_as_list_no_update do
  15. remove_deleted
  16. update_order
  17. end
  18. end
  19. end
  20. # Mass-update KB menu items
  21. #
  22. # @param [KnowledgeBase] knowledge_base
  23. # @param [[<Hash>]] params @see .update_location_params!
  24. #
  25. # @return [<KnowledgeBase::MenuItem>]
  26. def self.update_using_params!(knowledge_base, params)
  27. return if params.blank?
  28. params
  29. .map { |location_params| update_location_using_params! knowledge_base, location_params }.sum(&:reload)
  30. end
  31. # Mass-update KB menu items in a given location
  32. #
  33. # @param [KnowledgeBase] knowledge_base
  34. # @param [Hash] location_params
  35. #
  36. # @option location_params [Integer] :kb_locale_id
  37. # @option location_params [String] :location header or footer
  38. # @option location_params [[<Hash>]] :menu_items @see #update_order
  39. def self.update_location_using_params!(knowledge_base, location_params)
  40. action = new(
  41. knowledge_base.kb_locales.find(location_params[:kb_locale_id]),
  42. location_params[:location],
  43. location_params[:menu_items]
  44. )
  45. action.perform!
  46. action.scope
  47. end
  48. private
  49. def update_order
  50. old_items = scope.to_a
  51. @menu_items_data
  52. .reject { |elem| elem[:_destroy] }
  53. .each_with_index do |data_elem, index|
  54. item = old_items.find { |record| record.id == data_elem[:id] } || scope.build
  55. item.position = index
  56. item.title = data_elem[:title]
  57. item.url = data_elem[:url]
  58. item.new_tab = data_elem[:new_tab]
  59. item.save!
  60. end
  61. end
  62. def remove_deleted
  63. @menu_items_data
  64. .select { |elem| elem[:_destroy] }
  65. .pluck(:id)
  66. .tap { |array| @kb_locale.menu_items.where(id: array).destroy_all }
  67. end
  68. def all_ids_present?
  69. old_ids = scope.pluck(:id)
  70. new_ids = @menu_items_data.map { |elem| elem[:id]&.to_i }.compact
  71. old_ids.sort == new_ids.sort
  72. end
  73. def raise_unprocessable
  74. raise Exceptions::UnprocessableEntity, 'Provide position of all items in scope'
  75. end
  76. end
  77. end