class Api::ReleasesController < Api::ApiController include ProjectContext include CreateReleasableJobs before_action :set_project, only: [:index] before_action :set_release, only: [:show, :update] before_action :set_template_and_project, only: [:create] def index render jsonapi: releases, class: { "#{model_name.camelize}": index_serializable } end def show handle_response(@release) end def create params_without_photo = release_create_params.except(:photos, :person_photo) release = filtered_releases.new(params_without_photo) release.project_id = @project.id release.contract_template_id = @contract_template.id handle_attachments(release, release_create_params[:photos]) release.save!(context: :native) log_create_analytics after_create(release) handle_response(release, :created) end def update if model_name == "acquired_media_release" authorize @release, :update_file_infos? @release.attributes = release_create_params @release.save! else authorize @release, :update_photos? handle_attachments(@release, release_create_params[:photos]) @release.save! end handle_response(@release) end def handle_response(release, status = :ok) if model_name == "acquired_media_release" mapping = { "#{model_name.camelize}": SerializableAcquiredMediaRelease, FileInfo: SerializableFileInfo } render jsonapi: release, status: status, class: mapping, include: [:file_infos] else mapping = { "#{model_name.camelize}": show_serializable, "ActiveStorage::Attachment".to_sym => ActiveStorage::SerializableAttachment, } render jsonapi: release, status: status, class: mapping, include: [:photos, :guardian_photos] end end def model_name raise "Please specify model name underscored and lowercase e.g. appearance_release" end def model_constant model_name.camelize.constantize end def attributes_for_index raise "Please specify attributes for index" end def index_serializable name = model_name attributes_to_send = attributes_for_index Class.new(JSONAPI::Serializable::Resource) do type name attributes_to_send.each do |attr| attribute attr.to_sym end end end def show_serializable name = model_name constant = model_constant Class.new(JSONAPI::Serializable::Resource) do type name constant.new.attributes.keys.each do |attr| attribute attr.to_sym end if ["appearance_release", "talent_release"].include?(name) has_many :guardian_photos do data do [@object.guardian_photo.try(:attachment)].compact end meta do { count: @object.try(:guardian_photo).try(:attached?) ? 1 : 0 } end end end unless name == "acquired_media_release" has_many :photos do if name == "appearance_release" data do [@object.photo.attachment] end end meta do { count: @object.photos.size } end end end end end def create_deserializable constant = model_constant Class.new(JSONAPI::Deserializable::Resource) do constant.new.attributes.keys.except(:created_at, :updated_at, :id, :user_id).each do |attr| attribute attr.to_sym end end end def handle_attachments(release, params_photos) photos = params_photos || [] photos.each do |photo| photo[:io] = StringIO.new(Base64.decode64(photo[:io])) release.photos.attach(io: photo[:io], filename: photo[:filename]) end end private def releases date = Date.parse(params.fetch(:updated_since, Date.new.to_s)) table = model_constant.table_name policy_scope(model_constant.where(["#{table}.project_id = ? and #{table}.updated_at >= ?", @project.id, date])) end def set_release @release = model_constant.find(params[:id]) end def set_template_and_project @contract_template = ContractTemplate.find(params[:contract_template_id]) @project = @contract_template.project end def filtered_releases if @project.present? policy_scope(@project.public_send(model_name.pluralize)) else releases end end def release_create_params parameters = params.require(model_name).permit! keys = model_constant.new.attributes.keys + [:guardian_photo, :person_photo, :photos, :signature, :signature_base64, :file_infos_attributes] parameters[:signature_base64] = parameters[:signature] parameters = parameters.slice(*keys).except(:created_at, :updated_at, :id, :user_id, :signature) parameters end def log_create_analytics TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_native_release, release_type: model_constant.to_s, account: @account, user_agent: request.user_agent, user_ip: request.remote_ip, application: :ios) end end