DRY map exporting with policy_scoping

This commit is contained in:
Devin Howard 2016-03-26 11:31:55 +08:00
parent 14bdc8546b
commit d3649f1d26
5 changed files with 102 additions and 47 deletions

View file

@ -85,11 +85,24 @@ class MapsController < ApplicationController
respond_with(@allmappers, @allmappings, @allsynapses, @alltopics, @allmessages, @map) respond_with(@allmappers, @allmappings, @allsynapses, @alltopics, @allmessages, @map)
} }
format.json { render json: @map } format.json { render json: @map }
format.csv { send_data @map.to_csv } format.csv { redirect_to :export }
format.xls format.xls { redirect_to :export }
end end
end end
# GET maps/:id/export
def export
map = Map.find(params[:id])
authorize map
exporter = MapExportService(current_user, map)
respond_to do |format|
format.json { render json: exporter.json }
format.csv { send_data exporter.csv }
format.xls { @spreadsheet = exporter.xls }
end
end
# GET maps/:id/contains # GET maps/:id/contains
def contains def contains
@map = Map.find(params[:id]) @map = Map.find(params[:id])

View file

@ -84,50 +84,6 @@ class Map < ActiveRecord::Base
json json
end end
def to_spreadsheet
spreadsheet = []
spreadsheet << ["Topics"]
spreadsheet << ["Id", "Name", "Metacode", "X", "Y", "Description", "Link", "User", "Permission"]
self.topicmappings.each do |mapping|
topic = mapping.mappable
next if topic.nil?
spreadsheet << [
topic.id,
topic.name,
topic.metacode.name,
mapping.xloc,
mapping.yloc,
topic.desc,
topic.link,
topic.user.name,
topic.permission
]
end
spreadsheet << []
spreadsheet << ["Synapses"]
spreadsheet << ["Id", "Description", "Category", "Topic1", "Topic2", "User", "Permission"]
self.synapses.each do |synapse|
spreadsheet << [
synapse.id,
synapse.desc,
synapse.category,
synapse.node1_id,
synapse.node2_id,
synapse.user.name,
synapse.permission
]
end
spreadsheet
end
def to_csv(options = {})
CSV.generate(options) do |csv|
to_spreadsheet.each do |line|
csv << line
end
end
end
def decode_base64(imgBase64) def decode_base64(imgBase64)
decoded_data = Base64.decode64(imgBase64) decoded_data = Base64.decode64(imgBase64)

View file

@ -0,0 +1,84 @@
class MapExportService < Struct.new(:user, :map)
def json
# marshal_dump turns OpenStruct into a Hash
{
topics: exportable_topics.map(:marshal_dump),
synapses: exportable_synapses.map(:marshal_dump)
}
end
def csv(options = {})
CSV.generate(options) do |csv|
to_spreadsheet.each do |line|
csv << line
end
end
end
def xls
to_spreadsheet
end
private
def topic_headings
[:id, :name, :metacode, :x, :y, :description, :link, :user, :permission]
end
def synapse_headings
[:topic1, :topic2, :category, :description, :user, :permission]
end
def exportable_topics
visible_topics ||= Pundit.policy_scope!(@user, @map.topics)
topic_mappings = Mapping.includes(mappable: [:metacode, :user])
.where(mappable: visible_topics, map: @map)
topic_mappings.map do |mapping|
topic = mapping.mappable
OpenStruct.new(
id: topic.id,
name: topic.name,
metacode: topic.metacode.name,
x: mapping.xloc,
y: mapping.yloc,
description: topic.desc,
link: topic.link,
user: topic.user.name,
permission: topic.permission
)
end
end
def exportable_synapses
visible_synapses = Pundit.policy_scope!(@user, @map.synapses)
visible_synapses.map do |synapse|
OpenStruct.new(
topic1: synapse.node1_id,
topic2: synapse.node2_id,
category: synapse.category,
description: synapse.desc,
user: synapse.user.name,
permission: synapse.permission
)
end
end
def to_spreadsheet
spreadsheet = []
spreadsheet << ["Topics"]
spreadsheet << topic_headings.map(:capitalize)
exportable_topics.each do |topics|
# convert exportable_topics into an array of arrays
topic_headings.map do { |h| topics.send(h) }
end
spreadsheet << []
spreadsheet << ["Synapses"]
spreadsheet << synapse_headings.map(:capitalize)
exportable_synapses.each do |synapse|
# convert exportable_synapses into an array of arrays
synapse_headings.map do { |h| synapse.send(h) }
end
spreadsheet
end
end

View file

@ -1,5 +1,5 @@
<table> <table>
<% @map.to_spreadsheet.each do |line| %> <% @spreadsheet.each do |line| %>
<tr> <tr>
<% line.each do |field| %> <% line.each do |field| %>
<td><%= field %></td> <td><%= field %></td>

View file

@ -36,6 +36,8 @@ Metamaps::Application.routes.draw do
get 'topics/:id/relatives', to: 'topics#relatives', as: :relatives get 'topics/:id/relatives', to: 'topics#relatives', as: :relatives
resources :maps, except: [:index, :new, :edit] resources :maps, except: [:index, :new, :edit]
get 'maps/:id/export', to: 'maps#export'
get 'explore/active', to: 'maps#activemaps' get 'explore/active', to: 'maps#activemaps'
get 'explore/featured', to: 'maps#featuredmaps' get 'explore/featured', to: 'maps#featuredmaps'
get 'explore/mine', to: 'maps#mymaps' get 'explore/mine', to: 'maps#mymaps'