diff --git a/app/controllers/api/v1/markers_controller.rb b/app/controllers/api/v1/markers_controller.rb index 8eaf7767df8..dac77fa14ff 100644 --- a/app/controllers/api/v1/markers_controller.rb +++ b/app/controllers/api/v1/markers_controller.rb @@ -8,37 +8,39 @@ class Api::V1::MarkersController < Api::BaseController def index with_read_replica do - @markers = current_user.markers.where(timeline: Array(params[:timeline])).index_by(&:timeline) + @markers = current_user_markers end - - render json: serialize_map(@markers) + render json: marker_timeline_presenter, serializer: REST::MarkerTimelineSerializer end def create - Marker.transaction do - @markers = {} - - resource_params.each_pair do |timeline, timeline_params| - @markers[timeline] = current_user.markers.find_or_create_by(timeline: timeline) - @markers[timeline].update!(timeline_params) - end - end - - render json: serialize_map(@markers) + @markers = create_markers_from_params + render json: marker_timeline_presenter, serializer: REST::MarkerTimelineSerializer rescue ActiveRecord::StaleObjectError render json: { error: 'Conflict during update, please try again' }, status: 409 end private - def serialize_map(map) - serialized = {} + def marker_timeline_presenter + MarkerTimelinePresenter.new(@markers) + end - map.each_pair do |key, value| - serialized[key] = ActiveModelSerializers::SerializableResource.new(value, serializer: REST::MarkerSerializer).as_json + def current_user_markers + current_user.markers.where(timeline: Array(params[:timeline])) + end + + def create_markers_from_params + [].tap do |markers| + Marker.transaction do + resource_params.each_pair do |timeline, timeline_params| + current_user.markers.find_or_create_by(timeline: timeline).tap do |marker| + marker.update!(timeline_params) + markers << marker + end + end + end end - - Oj.dump(serialized) end def resource_params diff --git a/app/presenters/marker_timeline_presenter.rb b/app/presenters/marker_timeline_presenter.rb new file mode 100644 index 00000000000..dd80f18c390 --- /dev/null +++ b/app/presenters/marker_timeline_presenter.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +class MarkerTimelinePresenter + include ActiveModel::Model + + alias read_attribute_for_serialization send + + attr_reader :markers + + def initialize(markers) + @markers = markers + end + + Marker::TIMELINES.each do |timeline| + define_method timeline.to_sym do + markers.find { |marker| marker.timeline == timeline } + end + end + + def timeline_present?(value) + markers.map(&:timeline).include?(value) + end +end diff --git a/app/serializers/rest/marker_timeline_serializer.rb b/app/serializers/rest/marker_timeline_serializer.rb new file mode 100644 index 00000000000..14d221b2900 --- /dev/null +++ b/app/serializers/rest/marker_timeline_serializer.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class REST::MarkerTimelineSerializer < ActiveModel::Serializer + Marker::TIMELINES.each do |timeline| + has_one timeline.to_sym, + if: -> { timeline_present?(timeline) }, + serializer: REST::MarkerSerializer + end + + delegate :timeline_present?, to: :object +end