diff --git a/lib/core_ext/active_record/calculations/pluck_as_hash.rb b/lib/core_ext/active_record/calculations/pluck_as_hash.rb new file mode 100644 index 000000000..5407dd65b --- /dev/null +++ b/lib/core_ext/active_record/calculations/pluck_as_hash.rb @@ -0,0 +1,35 @@ +require 'active_record/relation/calculations' + +module ActiveRecord + module Calculations + # plucks attributes and create a hash instead of returning an array + # + # @see ActiveRecord::Calculations#pluck + # + # @param [] attributes to fetch + # + # @return [Any>] + # + # @example + # Ticket.all.pluck_as_hash(:title) # [{title: 'A'}, {title: 'B'}] + # Ticket.all.pluck_as_hash(:title, :owner_id) # [{title: 'A', owner_id: 1}, {title: 'B', owner_id: 2}] + def pluck_as_hash(*column_names) + column_names.flatten! # flatten args in case array was given + + klass.enforce_raw_sql_whitelist(column_names) # keep up deprection as in #pluck to ensure smooth Rails 6 transition + + pluck(*arel_columns(column_names)) + .map { |elem| pluck_as_hash_map(column_names, elem) } + end + + private + + def pluck_as_hash_map(keys, values) + if keys.one? + Hash[keys.first, values] + else + keys.zip(values).to_h + end + end + end +end diff --git a/lib/excel_sheet/ticket.rb b/lib/excel_sheet/ticket.rb index cf2a802bd..6dc7a77c5 100644 --- a/lib/excel_sheet/ticket.rb +++ b/lib/excel_sheet/ticket.rb @@ -48,23 +48,19 @@ class ExcelSheet::Ticket < ExcelSheet header.concat(@additional_attributes_header) if @additional_attributes_header # ObjectManager attributes - objects = ObjectManager::Attribute.where(active: true, - to_create: false, - object_lookup_id: ObjectLookup.lookup(name: 'Ticket').id) - .pluck(:name, :display, :data_type, :data_option) - .map { |name, display, data_type, data_option| { name: name, display: display, data_type: data_type, data_option: data_option, width: 20 } } - objects.each do |object| - already_exists = false - header.each do |local_header| - next if local_header[:name] != object[:name] - - already_exists = true - break - end - next if already_exists - - header.push object - end + ObjectManager::Attribute + .where( + active: true, + to_create: false, + object_lookup: ObjectLookup.lookup(name: 'Ticket') + ) + .where.not( + name: header.pluck(:name), + display: header.pluck(:display) + ) + .pluck_as_hash(:name, :display, :data_type, :data_option) + .each { |elem| elem[:width] = 20 } + .then { |objects| header.concat(objects) } header.concat([ { display: 'Created At', name: 'created_at', width: 18, data_type: 'datetime' }, diff --git a/spec/lib/core_ext/active_record/calculations/pluck_as_hash_spec.rb b/spec/lib/core_ext/active_record/calculations/pluck_as_hash_spec.rb new file mode 100644 index 000000000..be816560a --- /dev/null +++ b/spec/lib/core_ext/active_record/calculations/pluck_as_hash_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe ActiveRecord::Calculations do + describe '#pluck_as_hash' do + let(:ticket) { create(:ticket) } + + it 'returns array with the hash' do + result = Ticket.where(id: ticket.id).pluck_as_hash(:title) + expect(result).to eq [{ title: ticket.title }] + end + + it 'works given multiple attributes' do + result = Ticket.where(id: ticket.id).pluck_as_hash(:title, :id) + expect(result).to eq [{ title: ticket.title, id: ticket.id }] + end + + it 'works given array' do + result = Ticket.where(id: ticket.id).pluck_as_hash(%i[title id]) + expect(result).to eq [{ title: ticket.title, id: ticket.id }] + end + end +end diff --git a/spec/lib/excel_sheet/ticket_spec.rb b/spec/lib/excel_sheet/ticket_spec.rb new file mode 100644 index 000000000..bcf622d9b --- /dev/null +++ b/spec/lib/excel_sheet/ticket_spec.rb @@ -0,0 +1,29 @@ +require 'rails_helper' + +RSpec.describe ExcelSheet::Ticket do + let(:ticket) { create(:ticket) } + let(:tag_name) { 'foo' } + let(:instance) { described_class.new(title: 'some title', ticket_ids: [ticket.id], timezone: 'Europe/Berlin', locale: 'de-de') } + + before do + Tag.tag_add(object: 'Ticket', item: tag_name, o_id: 1, created_by_id: 1) + end + + describe '#ticket_header' do + it 'has Tags once' do + tags_count = instance.ticket_header.count { |elem| elem[:display] == 'Tags' } + + expect(tags_count).to eq 1 + end + + it 'has 31 column in default configuration' do + tags_count = instance.ticket_header.count + + expect(tags_count).to eq 31 + end + + it 'all elements have width attribute' do + expect(instance.ticket_header).to be_all(have_key(:width)) + end + end +end