Class: Mensa::Tables::ExportsController

Inherits:
ApplicationController
  • Object
show all
Defined in:
app/controllers/mensa/tables/exports_controller.rb

Overview

Lists a user’s available downloads for a table and creates new export requests. Generating the CSV happens asynchronously in Mensa::ExportJob; both the export button badge and the downloads list are refreshed via Turbo streams once the job completes.

Instance Method Summary collapse

Instance Method Details

#createObject

Creates a new export for the current user and enqueues the job that generates and attaches the CSV.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'app/controllers/mensa/tables/exports_controller.rb', line 19

def create
  export = Mensa::Export.new(
    table_name: params[:table_id],
    table_view_id: params[:table_view_id].presence,
    user: current_mensa_user,
    format: params[:export_format].to_s.presence_in(Mensa::Export::FORMATS) || "csv_excel",
    scope: params[:scope].to_s.presence_in(Mensa::Export::SCOPES) || "all",
    config: params.permit(:query, :page, order: {}, filters: {}).to_h,
    status: "pending"
  )

  if export.save
    Mensa::ExportJob.perform_later(export)

    respond_to do |format|
      format.turbo_stream { render turbo_stream: [list_stream, badge_stream] }
      format.json { render json: {id: export.id}, status: :created }
    end
  else
    respond_to do |format|
      format.turbo_stream { head :unprocessable_entity }
      format.json { render json: {errors: export.errors.full_messages}, status: :unprocessable_entity }
    end
  end
end

#downloadObject

Streams the generated CSV and then removes the export, purging the attached asset. Downloads are single-use: routing them through the controller (instead of a direct Active Storage link) gives us a hook to delete the Mensa::Export record and free the stored file afterwards.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'app/controllers/mensa/tables/exports_controller.rb', line 49

def download
  export = exports.find(params[:id])
  return head :not_found unless export.downloadable?

  data = export.asset.download
  filename = export.asset.filename.to_s.presence || export.filename.presence || "#{export.table_name}_export.csv"
  content_type = export.asset.content_type.presence || "text/csv"

  send_data data, filename: filename, type: content_type, disposition: "attachment"

  # Clean up after a successful send. `has_one_attached :asset` purges the
  # blob when the record is destroyed (dependent: :purge_later). Never let
  # cleanup failures break the download itself.
  begin
    export.destroy
    Mensa::Export.broadcast_refresh(export.table_name, export.user)
  rescue => e
    Mensa.config.logger&.warn("Mensa::Export cleanup failed for #{export.id}: #{e.class}: #{e.message}")
  end
end

#indexObject

Returns the current downloads list for the table, used to refresh the contents of the export dialog when it is opened.



10
11
12
13
14
15
# File 'app/controllers/mensa/tables/exports_controller.rb', line 10

def index
  respond_to do |format|
    format.turbo_stream { render turbo_stream: list_stream }
    format.html { render partial: "mensa/exports/list", locals: list_locals }
  end
end