dossier 2.7.1 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/{README.markdown → README.md} +10 -5
- data/Rakefile +1 -0
- data/app/controllers/dossier/reports_controller.rb +9 -38
- data/app/helpers/dossier/application_helper.rb +7 -1
- data/app/views/dossier/layouts/application.html.haml +6 -0
- data/app/views/dossier/reports/multi.html.haml +8 -3
- data/app/views/dossier/reports/show.html.haml +4 -2
- data/config/routes.rb +2 -2
- data/lib/dossier.rb +4 -8
- data/lib/dossier/adapter/active_record.rb +1 -1
- data/lib/dossier/formatter.rb +20 -3
- data/lib/dossier/multi_report.rb +17 -9
- data/lib/dossier/naming.rb +51 -0
- data/lib/dossier/renderer.rb +63 -0
- data/lib/dossier/report.rb +22 -7
- data/lib/dossier/responder.rb +34 -0
- data/lib/dossier/result.rb +5 -7
- data/lib/dossier/stream_csv.rb +10 -3
- data/lib/dossier/version.rb +1 -1
- data/lib/dossier/view_context_with_report_formatter.rb +7 -0
- data/lib/dossier/xls.rb +2 -2
- data/lib/generators/dossier/views/templates/show.html.haml +5 -3
- data/spec/dossier/adapter/active_record_spec.rb +1 -1
- data/spec/dossier/formatter_spec.rb +38 -3
- data/spec/dossier/multi_report_spec.rb +18 -1
- data/spec/dossier/naming_spec.rb +29 -0
- data/spec/dossier/renderer_spec.rb +57 -0
- data/spec/dossier/report_spec.rb +23 -2
- data/spec/dossier/responder_spec.rb +59 -0
- data/spec/dossier/result_spec.rb +4 -0
- data/spec/dossier/stream_csv_spec.rb +75 -0
- data/spec/dossier_spec.rb +0 -13
- data/spec/dummy/app/controllers/site_controller.rb +0 -4
- data/spec/dummy/app/reports/cats/are/super_fun_report.rb +9 -0
- data/spec/dummy/app/reports/combination_report.rb +9 -0
- data/spec/{support → dummy/app}/reports/employee_report.rb +0 -0
- data/spec/{support → dummy/app}/reports/employee_with_custom_client_report.rb +0 -0
- data/spec/dummy/app/reports/employee_with_custom_view_report.rb +27 -0
- data/spec/dummy/app/reports/hello_my_friends_report.rb +2 -0
- data/spec/{support → dummy/app}/reports/test_report.rb +0 -0
- data/spec/dummy/app/views/dossier/reports/combination/_options.html.haml +4 -0
- data/spec/dummy/app/views/dossier/reports/employee_with_custom_view.html.haml +5 -1
- data/spec/dummy/app/views/dossier/reports/employee_with_custom_view/_options.html.haml +6 -0
- data/spec/dummy/config/database.yml.travis +5 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +3865 -0
- data/spec/dummy/log/test.log +44084 -0
- data/spec/dummy/tmp/cache/assets/CEA/5A0/sprockets%2Fc0534884cbc43494a05d9e957ea1298d +0 -0
- data/spec/dummy/tmp/cache/assets/D40/0D0/sprockets%2F15a6bb0a1346b6d7fe859c14bf729a49 +0 -0
- data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/cache/assets/D51/510/sprockets%2Fca0353abc266080173bbc3c13efa935a +0 -0
- data/spec/dummy/tmp/cache/assets/D6C/400/sprockets%2F7fa180a6e05c7ca4346ef58c54bb30f8 +0 -0
- data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/{dossier_test → tmp/restart.txt} +0 -0
- data/spec/features/combination_report_spec.rb +13 -10
- data/spec/features/employee_spec.rb +76 -0
- data/spec/{requests → features}/employee_with_custom_client_spec.rb +3 -2
- data/spec/{requests → features}/employee_with_custom_controller_spec.rb +3 -2
- data/spec/features/namespaced_report_spec.rb +15 -0
- data/spec/fixtures/db/mysql2.yml.travis +4 -0
- data/spec/fixtures/db/sqlite3.yml.travis +2 -0
- data/spec/helpers/dossier/application_helper_spec.rb +24 -0
- data/spec/spec_helper.rb +11 -0
- metadata +99 -92
- data/spec/fixtures/reports/employee.html +0 -54
- data/spec/fixtures/reports/employee_with_custom_client.html +0 -54
- data/spec/fixtures/reports/employee_with_custom_view.html +0 -15
- data/spec/fixtures/reports/employee_with_footer.html +0 -56
- data/spec/fixtures/reports/employee_with_parameters.html +0 -38
- data/spec/requests/employee_spec.rb +0 -61
- data/spec/support/reports/combination_report.rb +0 -8
- data/spec/support/reports/employee_with_custom_view_report.rb +0 -8
- data/spec/support/reports/hello_my_friends_report.rb +0 -6
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: b964aa00e953df017cd8772cd0ed975301b841bd
|
|
4
|
+
data.tar.gz: c8faa33c28dec8b77a253918d089eea36d41c06d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 4557b660e38d7b8a6b8aeb4bd7a7579ae0bc5eeea214bf3a6a02bd45330b95bd120bacb8cf9905cf5c4bf47922f6f37f7d57ba2ffff6bc8e660867556e02653a
|
|
7
|
+
data.tar.gz: 27c413936b6b22c1c4f977eb7546419b92f8804df1908e6346b82ce3f3f74e0bdcc42b182d7300a799b2f43c0658a25d7d12c8c869455036ef0b0ae6e292c1a4
|
|
@@ -5,7 +5,11 @@ Dossier is a Rails engine that turns SQL into reports. Reports can be easily ren
|
|
|
5
5
|
- If you **hate** SQL, you can use whatever tool you like to generate it; for example, ActiveRecord's `to_sql`.
|
|
6
6
|
- If you **love** SQL, you can use every feature your database supports.
|
|
7
7
|
|
|
8
|
+
[](https://rubygems.org/gems/dossier)
|
|
8
9
|
[](https://codeclimate.com/github/adamhunter/dossier)
|
|
10
|
+
[](https://travis-ci.org/adamhunter/dossier)
|
|
11
|
+
[](https://coveralls.io/r/adamhunter/dossier?branch=master)
|
|
12
|
+
[](https://gemnasium.com/adamhunter/dossier)
|
|
9
13
|
|
|
10
14
|
## Setup
|
|
11
15
|
|
|
@@ -75,10 +79,11 @@ By default, headers are generated by calling `titleize` on the column name from
|
|
|
75
79
|
class ProductMarginReport < Dossier::Report
|
|
76
80
|
# ...
|
|
77
81
|
def format_header(column_name)
|
|
78
|
-
{
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
+
custom_headers = {
|
|
83
|
+
margin_percentage: 'Margin %',
|
|
84
|
+
absolute_margin: 'Margin $'
|
|
85
|
+
}
|
|
86
|
+
custom_headers.fetch(column_name.to_sym) { super }
|
|
82
87
|
end
|
|
83
88
|
end
|
|
84
89
|
```
|
|
@@ -206,7 +211,7 @@ end
|
|
|
206
211
|
### Dossier for APIs
|
|
207
212
|
|
|
208
213
|
```ruby
|
|
209
|
-
class
|
|
214
|
+
class Api::ProjectsController < Api::ApplicationController
|
|
210
215
|
|
|
211
216
|
def snapshot
|
|
212
217
|
render json: ProjectStatusReport.new(project: @project).results.hashes
|
data/Rakefile
CHANGED
|
@@ -1,51 +1,23 @@
|
|
|
1
1
|
module Dossier
|
|
2
2
|
class ReportsController < ApplicationController
|
|
3
|
+
include ViewContextWithReportFormatter
|
|
4
|
+
|
|
5
|
+
self.responder = Dossier::Responder
|
|
6
|
+
|
|
7
|
+
respond_to :html, :json, :csv, :xls, only: :show
|
|
8
|
+
|
|
3
9
|
def show
|
|
4
|
-
|
|
5
|
-
format.html do
|
|
6
|
-
begin
|
|
7
|
-
render template: "dossier/reports/#{report_class.report_name}", locals: {report: report}
|
|
8
|
-
rescue ActionView::MissingTemplate => e
|
|
9
|
-
render template: 'dossier/reports/show', locals: {report: report}
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
format.json do
|
|
14
|
-
render :json => report.results.hashes
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
format.csv do
|
|
18
|
-
set_content_disposition!
|
|
19
|
-
self.response_body = StreamCSV.new(report.raw_results.arrays)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
format.xls do
|
|
23
|
-
set_content_disposition!
|
|
24
|
-
self.response_body = Xls.new(report.raw_results.arrays)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
10
|
+
respond_with(report)
|
|
27
11
|
end
|
|
28
12
|
|
|
29
13
|
def multi
|
|
30
|
-
|
|
31
|
-
format.html do
|
|
32
|
-
begin
|
|
33
|
-
render template: "dossier/reports/#{report_class.report_name}", locals: {multi: report}
|
|
34
|
-
rescue ActionView::MissingTemplate => e
|
|
35
|
-
render template: 'dossier/reports/multi', locals: {multi: report}
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
14
|
+
render template: 'dossier/reports/multi', locals: {multi: report}
|
|
39
15
|
end
|
|
40
16
|
|
|
41
17
|
private
|
|
42
18
|
|
|
43
19
|
def report_class
|
|
44
|
-
Dossier.name_to_class(params[:report])
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def set_content_disposition!
|
|
48
|
-
headers["Content-Disposition"] = %[attachment;filename=#{params[:report]}-report_#{Time.now.strftime('%m-%d-%Y_%H-%M-%S')}.#{params[:format]}]
|
|
20
|
+
Dossier::Naming.name_to_class(params[:report])
|
|
49
21
|
end
|
|
50
22
|
|
|
51
23
|
def report
|
|
@@ -55,6 +27,5 @@ module Dossier
|
|
|
55
27
|
def options_params
|
|
56
28
|
params[:options].presence || {}
|
|
57
29
|
end
|
|
58
|
-
|
|
59
30
|
end
|
|
60
31
|
end
|
|
@@ -2,7 +2,13 @@ module Dossier
|
|
|
2
2
|
module ApplicationHelper
|
|
3
3
|
|
|
4
4
|
def formatted_dossier_report_path(format, report)
|
|
5
|
-
dossier_report_path(format: format, options: report.options, report: report.
|
|
5
|
+
dossier_report_path(format: format, options: report.options, report: report.report_name)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def render_options(report)
|
|
9
|
+
return if report.parent
|
|
10
|
+
render "dossier/reports/#{report.report_name}/options", report: report
|
|
11
|
+
rescue ActionView::MissingTemplate
|
|
6
12
|
end
|
|
7
13
|
|
|
8
14
|
end
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
%
|
|
2
|
-
-
|
|
3
|
-
|
|
1
|
+
%div{id: multi.dom_id}
|
|
2
|
+
%h1.dossier-multi-header
|
|
3
|
+
= multi.formatted_title
|
|
4
|
+
|
|
5
|
+
= render_options(multi)
|
|
6
|
+
|
|
7
|
+
- multi.reports.each do |report|
|
|
8
|
+
= report.render layout: false
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
%
|
|
1
|
+
%h2= report.formatted_title
|
|
2
2
|
|
|
3
|
-
= link_to 'Download CSV',
|
|
3
|
+
= link_to 'Download CSV', formatted_dossier_report_path('csv', report), class: 'download-csv'
|
|
4
|
+
|
|
5
|
+
= render_options(report)
|
|
4
6
|
|
|
5
7
|
%table
|
|
6
8
|
%thead
|
data/config/routes.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Rails.application.routes.draw do
|
|
2
2
|
|
|
3
|
-
get "reports
|
|
4
|
-
get "multi/reports
|
|
3
|
+
get "reports/*report", to: 'dossier/reports#show', as: :dossier_report
|
|
4
|
+
get "multi/reports/*report", to: 'dossier/reports#multi', as: :dossier_multi_report
|
|
5
5
|
|
|
6
6
|
end
|
data/lib/dossier.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
require "dossier/engine"
|
|
2
|
+
require "dossier/naming"
|
|
3
|
+
require "dossier/view_context_with_report_formatter"
|
|
2
4
|
require "dossier/version"
|
|
3
5
|
|
|
4
6
|
module Dossier
|
|
@@ -18,14 +20,6 @@ module Dossier
|
|
|
18
20
|
configuration.client
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
def class_to_name(klass)
|
|
22
|
-
klass.name.underscore[0..-8]
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def name_to_class(name)
|
|
26
|
-
"#{name.split('_').map(&:capitalize).join}Report".constantize
|
|
27
|
-
end
|
|
28
|
-
|
|
29
23
|
class ExecuteError < StandardError; end
|
|
30
24
|
end
|
|
31
25
|
|
|
@@ -36,7 +30,9 @@ require "dossier/configuration"
|
|
|
36
30
|
require "dossier/formatter"
|
|
37
31
|
require "dossier/multi_report"
|
|
38
32
|
require "dossier/query"
|
|
33
|
+
require "dossier/renderer"
|
|
39
34
|
require "dossier/report"
|
|
35
|
+
require "dossier/responder"
|
|
40
36
|
require "dossier/result"
|
|
41
37
|
require "dossier/stream_csv"
|
|
42
38
|
require "dossier/xls"
|
|
@@ -15,7 +15,7 @@ module Dossier
|
|
|
15
15
|
|
|
16
16
|
def execute(query, report_name = nil)
|
|
17
17
|
# Ensure that SQL logs show name of report generating query
|
|
18
|
-
Result.new(connection.exec_query(*[query, report_name].compact))
|
|
18
|
+
Result.new(connection.exec_query(*["\n#{query}", report_name].compact))
|
|
19
19
|
rescue => e
|
|
20
20
|
raise Dossier::ExecuteError.new "#{e.message}\n\n#{query}"
|
|
21
21
|
end
|
data/lib/dossier/formatter.rb
CHANGED
|
@@ -1,18 +1,35 @@
|
|
|
1
1
|
module Dossier
|
|
2
2
|
module Formatter
|
|
3
|
+
include ActiveSupport::Inflector
|
|
4
|
+
include ActionView::Helpers::NumberHelper
|
|
3
5
|
extend self
|
|
4
|
-
extend ActiveSupport::Inflector
|
|
5
|
-
extend ActionView::Helpers::NumberHelper
|
|
6
6
|
|
|
7
7
|
def number_to_currency_from_cents(value)
|
|
8
8
|
number_to_currency(value /= 100.0)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
def number_to_dollars(value)
|
|
12
|
+
"$#{commafy_number(value, 2)}"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def commafy_number(value, precision = nil)
|
|
16
|
+
whole, fraction = value.to_s.split('.')
|
|
17
|
+
fraction = "%.#{precision}d" % ("0.#{fraction}".to_f.round(precision) * 10**precision).to_i if precision
|
|
18
|
+
[whole.to_i.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,"), fraction].compact.join('.')
|
|
19
|
+
end
|
|
20
|
+
|
|
11
21
|
def url_formatter
|
|
12
22
|
@url_formatter ||= UrlFormatter.new
|
|
13
23
|
end
|
|
14
24
|
|
|
15
|
-
|
|
25
|
+
def report_name(report)
|
|
26
|
+
titleize("#{report.report_name.split('/').last} Report")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# TODO figure out how to handle this better
|
|
30
|
+
# reports rendered with a system layout use this link_to instead of the
|
|
31
|
+
# correct one
|
|
32
|
+
# delegate :url_for, :link_to, :url_helpers, to: :url_formatter
|
|
16
33
|
|
|
17
34
|
class UrlFormatter
|
|
18
35
|
include ActionView::Helpers::UrlHelper
|
data/lib/dossier/multi_report.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
class Dossier::MultiReport
|
|
2
|
+
include Dossier::Naming
|
|
2
3
|
|
|
3
4
|
attr_accessor :options
|
|
4
5
|
|
|
@@ -6,24 +7,31 @@ class Dossier::MultiReport
|
|
|
6
7
|
attr_accessor :reports
|
|
7
8
|
end
|
|
8
9
|
|
|
9
|
-
def self.report_name
|
|
10
|
-
Dossier.class_to_name(self)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
10
|
def self.combine(*reports)
|
|
14
11
|
self.reports = reports
|
|
15
12
|
end
|
|
16
13
|
|
|
17
|
-
def self.report=(value)
|
|
18
|
-
value
|
|
19
|
-
end
|
|
20
|
-
|
|
21
14
|
def initialize(options = {})
|
|
22
15
|
self.options = options.dup.with_indifferent_access
|
|
23
16
|
end
|
|
24
17
|
|
|
25
18
|
def reports
|
|
26
|
-
@reports ||= self.class.reports.map
|
|
19
|
+
@reports ||= self.class.reports.map { |report|
|
|
20
|
+
report.new(options).tap { |r|
|
|
21
|
+
r.parent = self
|
|
22
|
+
}
|
|
23
|
+
}
|
|
27
24
|
end
|
|
28
25
|
|
|
26
|
+
def parent
|
|
27
|
+
nil
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def formatter
|
|
31
|
+
Module.new
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def dom_id
|
|
35
|
+
nil
|
|
36
|
+
end
|
|
29
37
|
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Dossier
|
|
2
|
+
module Naming
|
|
3
|
+
|
|
4
|
+
# not using ActiveSupport::Concern because ClassMethods
|
|
5
|
+
# must be extended after ActiveModel::Naming
|
|
6
|
+
def self.included(base)
|
|
7
|
+
base.extend ActiveModel::Naming
|
|
8
|
+
base.extend ClassMethods
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.class_to_name(klass)
|
|
12
|
+
(klass.name || anonymous_report).underscore[0..-8]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.name_to_class(name)
|
|
16
|
+
"#{name}_report".classify.constantize
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.anonymous_report
|
|
20
|
+
'AnonymousReport'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def to_key
|
|
24
|
+
[report_name]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def to_s
|
|
28
|
+
report_name
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
delegate :report_name, :formatted_title, to: "self.class"
|
|
32
|
+
|
|
33
|
+
module ClassMethods
|
|
34
|
+
def report_name
|
|
35
|
+
Dossier::Naming.class_to_name(self)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def formatted_title
|
|
39
|
+
Dossier::Formatter.report_name(self)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def model_name
|
|
43
|
+
@model_name ||= ActiveModel::Name.new(self, nil, superclass.name).tap do |name|
|
|
44
|
+
name.instance_variable_set(:@param_key, 'options')
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module Dossier
|
|
2
|
+
class Renderer
|
|
3
|
+
attr_reader :report
|
|
4
|
+
attr_writer :engine
|
|
5
|
+
|
|
6
|
+
def initialize(report)
|
|
7
|
+
@report = report
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def render(options = {})
|
|
11
|
+
render_template :custom, options
|
|
12
|
+
rescue ActionView::MissingTemplate => e
|
|
13
|
+
render_template :default, options
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def engine
|
|
17
|
+
@engine ||= Engine.new(report)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def render_template(template, options)
|
|
23
|
+
template = send("#{template}_template_path")
|
|
24
|
+
engine.render options.merge(template: template, locals: {report: report})
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def template_path(template)
|
|
28
|
+
"dossier/reports/#{template}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def custom_template_path
|
|
32
|
+
template_path(report.template)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def default_template_path
|
|
36
|
+
template_path('show')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
class Engine < AbstractController::Base
|
|
40
|
+
include AbstractController::Layouts
|
|
41
|
+
include ViewContextWithReportFormatter
|
|
42
|
+
attr_reader :report
|
|
43
|
+
|
|
44
|
+
layout 'dossier/layouts/application'
|
|
45
|
+
|
|
46
|
+
def self._helpers
|
|
47
|
+
Module.new do
|
|
48
|
+
include Rails.application.helpers
|
|
49
|
+
include Rails.application.routes_url_helpers
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self._view_paths
|
|
54
|
+
ActionController::Base.view_paths
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def initialize(report)
|
|
58
|
+
@report = report
|
|
59
|
+
super()
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
data/lib/dossier/report.rb
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
module Dossier
|
|
2
2
|
class Report
|
|
3
|
+
include Dossier::Naming
|
|
3
4
|
include ActiveSupport::Callbacks
|
|
4
|
-
extend ActiveModel::Naming
|
|
5
5
|
|
|
6
6
|
define_callbacks :build_query, :execute
|
|
7
7
|
|
|
8
8
|
attr_reader :options
|
|
9
|
+
attr_accessor :parent
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
class_attribute :formatter
|
|
12
|
+
class_attribute :template
|
|
13
|
+
|
|
14
|
+
self.formatter = Dossier::Formatter
|
|
15
|
+
|
|
16
|
+
delegate :formatter, :template, to: "self.class"
|
|
17
|
+
|
|
18
|
+
def self.inherited(base)
|
|
19
|
+
super
|
|
20
|
+
base.template = base.report_name
|
|
12
21
|
end
|
|
13
22
|
|
|
23
|
+
def self.filename
|
|
24
|
+
"#{report_name.parameterize}-report_#{Time.now.strftime('%m-%d-%Y_%H-%M-%S')}"
|
|
25
|
+
end
|
|
26
|
+
|
|
14
27
|
def initialize(options = {})
|
|
15
28
|
@options = options.dup.with_indifferent_access
|
|
16
29
|
end
|
|
@@ -38,10 +51,6 @@ module Dossier
|
|
|
38
51
|
tap { execute }
|
|
39
52
|
end
|
|
40
53
|
|
|
41
|
-
def formatter
|
|
42
|
-
Dossier::Formatter
|
|
43
|
-
end
|
|
44
|
-
|
|
45
54
|
def format_header(header)
|
|
46
55
|
formatter.titleize(header.to_s)
|
|
47
56
|
end
|
|
@@ -50,6 +59,12 @@ module Dossier
|
|
|
50
59
|
Dossier.client
|
|
51
60
|
end
|
|
52
61
|
|
|
62
|
+
def renderer
|
|
63
|
+
@renderer ||= Renderer.new(self)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
delegate :render, to: :renderer
|
|
67
|
+
|
|
53
68
|
private
|
|
54
69
|
|
|
55
70
|
def build_query
|