dynamic_reports 0.0.1 → 0.0.4
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.
- data/HISTORY +8 -1
- data/README +81 -23
- data/README.rdoc +247 -0
- data/dynamic_reports.gemspec +62 -0
- data/lib/dynamic_reports.rb +8 -2
- data/lib/dynamic_reports/reports.rb +66 -14
- data/lib/dynamic_reports/templates.rb +50 -7
- data/lib/dynamic_reports/views/default_report.html.erb +22 -53
- data/lib/dynamic_reports/views/default_report.html.haml +8 -36
- data/test/dynamic_reports.rb +18 -0
- data/test/dynamic_reports/charts_test.rb +61 -0
- data/test/dynamic_reports/reports_test.rb +77 -0
- data/test/dynamic_reports/templates_test.rb +3 -0
- data/test/dynamic_reports/views_test.rb +5 -0
- data/test/factories/records.rb +0 -0
- data/test/test_helper.rb +64 -0
- metadata +28 -18
- data/gemspec.rb +0 -24
data/HISTORY
CHANGED
data/README
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
= Dynamic Reports
|
2
2
|
|
3
3
|
A dynamic reporting engine for Ruby / Rails
|
4
|
-
|
4
|
+
|
5
5
|
== Reports
|
6
6
|
|
7
7
|
The dynamic reports gem was created to fill a HUGE hole that we felt existed in the
|
@@ -114,32 +114,90 @@
|
|
114
114
|
label_column "created_at"
|
115
115
|
end
|
116
116
|
|
117
|
-
==
|
118
|
-
|
119
|
-
The reports are, by default, stylized with an inline style sheet. The styles produce a nicely formatted grid with
|
120
|
-
a white on black header row and black on white columns with a gray border througout.
|
117
|
+
== External Links
|
121
118
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
119
|
+
Dynamic Reports supports linking from any column within your table. To add a link to a column, add the following
|
120
|
+
to a report definition:
|
121
|
+
|
122
|
+
link :column, url
|
123
|
+
|
124
|
+
For example:
|
125
|
+
|
126
|
+
class OrdersReport < DynamicReports::Report
|
127
|
+
title "Orders Report"
|
128
|
+
subtitle "All orders recorded in database"
|
129
|
+
columns :total, :created_at
|
130
|
+
|
131
|
+
link :total, '/report/daily_sales'
|
132
|
+
end
|
133
|
+
|
134
|
+
You can also pass parameters to the URL based on values from the underlying model. To pass a parameter, surround the
|
135
|
+
field name with {}. The parameter does NOT need to be a displayed, column. For example, you might want to pass
|
136
|
+
an external link an ID column but not display this column on the table.
|
137
|
+
|
138
|
+
For example:
|
139
|
+
|
140
|
+
class OrdersReport < DynamicReports::Report
|
141
|
+
title "Orders Report"
|
142
|
+
subtitle "All orders recorded in database"
|
143
|
+
columns :total, :created_at
|
144
|
+
|
145
|
+
link :total, '/report/item_sales?id={id}' # => Will substitute ID for the value of ID associated with that record
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
== Subreports
|
128
150
|
|
129
|
-
|
130
|
-
|
151
|
+
Dynamic Reports supports the display of a sub-report within any report. This is accomplished using the jQuery library
|
152
|
+
available at http://www.jquery.com.
|
153
|
+
|
154
|
+
Sub-reports are created using the same definition format that you would use to create a standard report. The only
|
155
|
+
difference is that it is displayed INLINE when an associated link is clicked.
|
156
|
+
|
157
|
+
A sub-report is defined using the same format as a LINK above, but is labeled as:
|
158
|
+
|
159
|
+
subreport :column, url
|
160
|
+
|
161
|
+
For example, if you wanted to show all sales and allow a user to click on a specific item to see all historic sales
|
162
|
+
inline for just that item, you would do the following:
|
163
|
+
|
164
|
+
IN CONTROLLER:
|
165
|
+
|
166
|
+
def orders
|
167
|
+
@orders = Order.find(:all, :limit => 25)
|
168
|
+
render :text => OrdersReport.on(@orders).to_html, :layout => "application"
|
169
|
+
end
|
170
|
+
|
171
|
+
def item_sales
|
172
|
+
@item_orders = Order.find_by_id(params[:id])
|
173
|
+
render :text => ItemSales.on(@orders).to_html, :layout => "application"
|
174
|
+
end
|
175
|
+
|
176
|
+
REPORT DEFINITIONS
|
177
|
+
|
178
|
+
class OrdersReport < DynamicReports::Report
|
179
|
+
title "Orders Report"
|
180
|
+
subtitle "All orders recorded in database"
|
181
|
+
columns :total, :created_at
|
182
|
+
|
183
|
+
subreport :total, '/report/item_sales?id={id}' # => Will substitute ID for the value of ID associated with that record
|
184
|
+
end
|
185
|
+
|
186
|
+
class ItemSales < DynamicReports::Report
|
187
|
+
columns :item, :price, :created_at
|
188
|
+
end
|
189
|
+
|
190
|
+
Subreports can also be nested.
|
191
|
+
|
192
|
+
== Rails Usage
|
131
193
|
|
132
|
-
|
133
|
-
|
194
|
+
The gem includes a stylesheet and javascript based on jQuery. To add both to your Rails project,
|
195
|
+
simply type "drsetup" from the project root. This will add:
|
134
196
|
|
135
|
-
|
136
|
-
|
137
|
-
.my_class_name table tr th {}
|
138
|
-
.my_class_name table tr td {}
|
139
|
-
.my_class_name .report_charts {} // all charts are displayed within this div
|
140
|
-
.my_class_name .report_chart {} // represents an individual chart
|
197
|
+
public/stylesheets/dynamic_reports.css (controls style of dynamic reports)
|
198
|
+
public/javascripts/dynamic_reports.js (controls display of subreports)
|
141
199
|
|
142
|
-
|
200
|
+
You can then modify these files as you see fit.
|
143
201
|
|
144
202
|
Inside the initializer block in config/environment.rb
|
145
203
|
|
@@ -179,7 +237,7 @@
|
|
179
237
|
== Thanks To
|
180
238
|
|
181
239
|
* Daniel Neighman
|
182
|
-
* Kenneth Kalmer
|
240
|
+
* Kenneth Kalmer & Nic Young
|
183
241
|
* Yehuda Katz
|
184
242
|
|
185
243
|
For their encouragement, feedback and advise.
|
data/README.rdoc
ADDED
@@ -0,0 +1,247 @@
|
|
1
|
+
= Dynamic Reports
|
2
|
+
|
3
|
+
A dynamic reporting engine for Ruby / Rails
|
4
|
+
|
5
|
+
== Reports
|
6
|
+
|
7
|
+
The dynamic reports gem was created to fill a HUGE hole that we felt existed in the
|
8
|
+
Ruby community - the ability to QUICKLY create stylized admin reports and charts for
|
9
|
+
people to use to view key metrics and data.
|
10
|
+
|
11
|
+
Sample uses include the ability to quickly display sales data if your an eShop, our
|
12
|
+
site metrics if you are recording your own site visits, or user feedback if you are storing
|
13
|
+
feedback in a model somewhere.
|
14
|
+
|
15
|
+
Basically, with DR you can create a stylized table of ANY information found in a model
|
16
|
+
(kind of like looking at the grid output from a GUI query analyzer) as well as add Google
|
17
|
+
Charts API powered line, pie, bar or column charts of any numeric data. All this can
|
18
|
+
be done by simply creating a report definition and feeding it your data.
|
19
|
+
|
20
|
+
While this library is usable in any Ruby application it was made mainly with Rails in mind.
|
21
|
+
Suppose we have an online store and we wish to add reporting to the admin area quickly and easily.
|
22
|
+
First we define a report in app/reports/orders_report.rb, something like:
|
23
|
+
|
24
|
+
class OrdersReport < DynamicReports::Report
|
25
|
+
title "Orders Report"
|
26
|
+
subtitle "All orders recorded in database"
|
27
|
+
columns :total, :created_at
|
28
|
+
end
|
29
|
+
|
30
|
+
Then in our admin/reports controller (this can be any controller) we define an action to deliver the report:
|
31
|
+
|
32
|
+
def orders
|
33
|
+
@orders = Order.find(:all, :limit => 25)
|
34
|
+
render :text => OrdersReport.on(@orders).to_html, :layout => "application"
|
35
|
+
end
|
36
|
+
|
37
|
+
This will render an html table containing some basic styling and containing the columns 'total' and 'created_at' from the order objects.
|
38
|
+
Note that the report Title will be "Orders Report" and it's name will be :orders_report
|
39
|
+
Report#on expects that it receives an object that responds to #each and
|
40
|
+
That each object that it iterates over is either a
|
41
|
+
* An object
|
42
|
+
* A Hash
|
43
|
+
that responds to a method / has keys for each column defined within the report.
|
44
|
+
|
45
|
+
|
46
|
+
Templating engines may also be specified, currently :erb and :haml are supported (we will soon be adding :csv and :pdf) like so:
|
47
|
+
|
48
|
+
render :text => OrdersReport.on(@orders).to_html(:engine => :haml), :layout => "application"
|
49
|
+
|
50
|
+
Note that erb is the default templating engine since it is available by default in Ruby.
|
51
|
+
|
52
|
+
Now let us extend our report definition to specify a template to use!
|
53
|
+
|
54
|
+
class OrdersReport < DynamicReports::Report
|
55
|
+
title "Orders Report"
|
56
|
+
subtitle "All orders recorded in database"
|
57
|
+
columns :total, :created_at
|
58
|
+
|
59
|
+
template :my_custom_template
|
60
|
+
end
|
61
|
+
|
62
|
+
This will look in app/views/reports/ for a template named "my_custom_template.html.erb" by default.
|
63
|
+
If you specify :engine => :haml then it will look for "my_custom_template.html.haml"
|
64
|
+
|
65
|
+
If you happen to have your report templates in a different location you can specify this as follows:
|
66
|
+
|
67
|
+
class OrdersReport < DynamicReports::Report
|
68
|
+
title "Orders Report"
|
69
|
+
subtitle "All orders recorded in database"
|
70
|
+
columns :total, :created_at
|
71
|
+
|
72
|
+
template :my_custom_template
|
73
|
+
views "app/views/admin/reports/"
|
74
|
+
end
|
75
|
+
|
76
|
+
And DynamicReports will look for the specified template in app/views/reports as well as app/views/admin/reports.
|
77
|
+
|
78
|
+
It is also worth pointing out that you can have as many dynamic reports in a view as you wish, simply include
|
79
|
+
each report render where desired within the view.
|
80
|
+
|
81
|
+
== Charts
|
82
|
+
|
83
|
+
Charts can be defined on a report easily. Let's say we wish to chart the total versus the item quantity sold for our Orders Report exmaple:
|
84
|
+
|
85
|
+
class OrdersReport < DynamicReports::Report
|
86
|
+
title "Orders Report"
|
87
|
+
subtitle "All orders recorded in database"
|
88
|
+
columns :total, :created_at
|
89
|
+
|
90
|
+
chart :total_vs_quantity do
|
91
|
+
columns :total, :quantity
|
92
|
+
label_column "created_at"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
This will render a *line* chart by default displaying the columns total and quantity.
|
97
|
+
Chart types may be specified easily:
|
98
|
+
|
99
|
+
type :bar
|
100
|
+
|
101
|
+
Available chart types are:
|
102
|
+
|
103
|
+
* :line (default)
|
104
|
+
* :bar
|
105
|
+
* :pie
|
106
|
+
|
107
|
+
Since DynamicReport's charts utilize the Google Chart API, you can easily extend each chart by passing a hash of chart options as part
|
108
|
+
of the block. The options are appended onto the request to the API so they should follow the Google's API commands (http://code.google.com/apis/chart/)
|
109
|
+
|
110
|
+
For example, to add min, max and average labels to the example chart, you would do something like this:
|
111
|
+
|
112
|
+
chart :total_vs_quantity, {:chxt => "r", :chxl => "0:|min|average|max"} do
|
113
|
+
columns :total, :quantity
|
114
|
+
label_column "created_at"
|
115
|
+
end
|
116
|
+
|
117
|
+
== External Links
|
118
|
+
|
119
|
+
Dynamic Reports supports linking from any column within your table. To add a link to a column, add the following
|
120
|
+
to a report definition:
|
121
|
+
|
122
|
+
link :column, url
|
123
|
+
|
124
|
+
For example:
|
125
|
+
|
126
|
+
class OrdersReport < DynamicReports::Report
|
127
|
+
title "Orders Report"
|
128
|
+
subtitle "All orders recorded in database"
|
129
|
+
columns :total, :created_at
|
130
|
+
|
131
|
+
link :total, '/report/daily_sales'
|
132
|
+
end
|
133
|
+
|
134
|
+
You can also pass parameters to the URL based on values from the underlying model. To pass a parameter, surround the
|
135
|
+
field name with {}. The parameter does NOT need to be a displayed, column. For example, you might want to pass
|
136
|
+
an external link an ID column but not display this column on the table.
|
137
|
+
|
138
|
+
For example:
|
139
|
+
|
140
|
+
class OrdersReport < DynamicReports::Report
|
141
|
+
title "Orders Report"
|
142
|
+
subtitle "All orders recorded in database"
|
143
|
+
columns :total, :created_at
|
144
|
+
|
145
|
+
link :total, '/report/item_sales?id={id}' # => Will substitute ID for the value of ID associated with that record
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
== Subreports
|
150
|
+
|
151
|
+
Dynamic Reports supports the display of a sub-report within any report. This is accomplished using the jQuery library
|
152
|
+
available at http://www.jquery.com.
|
153
|
+
|
154
|
+
Sub-reports are created using the same definition format that you would use to create a standard report. The only
|
155
|
+
difference is that it is displayed INLINE when an associated link is clicked.
|
156
|
+
|
157
|
+
A sub-report is defined using the same format as a LINK above, but is labeled as:
|
158
|
+
|
159
|
+
subreport :column, url
|
160
|
+
|
161
|
+
For example, if you wanted to show all sales and allow a user to click on a specific item to see all historic sales
|
162
|
+
inline for just that item, you would do the following:
|
163
|
+
|
164
|
+
IN CONTROLLER:
|
165
|
+
|
166
|
+
def orders
|
167
|
+
@orders = Order.find(:all, :limit => 25)
|
168
|
+
render :text => OrdersReport.on(@orders).to_html, :layout => "application"
|
169
|
+
end
|
170
|
+
|
171
|
+
def item_sales
|
172
|
+
@item_orders = Order.find_by_id(params[:id])
|
173
|
+
render :text => ItemSales.on(@orders).to_html, :layout => "application"
|
174
|
+
end
|
175
|
+
|
176
|
+
REPORT DEFINITIONS
|
177
|
+
|
178
|
+
class OrdersReport < DynamicReports::Report
|
179
|
+
title "Orders Report"
|
180
|
+
subtitle "All orders recorded in database"
|
181
|
+
columns :total, :created_at
|
182
|
+
|
183
|
+
subreport :total, '/report/item_sales?id={id}' # => Will substitute ID for the value of ID associated with that record
|
184
|
+
end
|
185
|
+
|
186
|
+
class ItemSales < DynamicReports::Report
|
187
|
+
columns :item, :price, :created_at
|
188
|
+
end
|
189
|
+
|
190
|
+
Subreports can also be nested.
|
191
|
+
|
192
|
+
== Rails Usage
|
193
|
+
|
194
|
+
The gem includes a stylesheet and javascript based on jQuery. To add both to your Rails project,
|
195
|
+
simply type "drsetup" from the project root. This will add:
|
196
|
+
|
197
|
+
public/stylesheets/dynamic_reports.css (controls style of dynamic reports)
|
198
|
+
public/javascripts/dynamic_reports.js (controls display of subreports)
|
199
|
+
|
200
|
+
You can then modify these files as you see fit.
|
201
|
+
|
202
|
+
Inside the initializer block in config/environment.rb
|
203
|
+
|
204
|
+
config.gem "dynamic_reports"
|
205
|
+
|
206
|
+
Then define your reports (as exampled above) in app/reports/*_report.rb
|
207
|
+
If you would like to customize the default report simply create your report templates
|
208
|
+
within app/views/reports/*_report.<content-type>.<engine>.
|
209
|
+
|
210
|
+
Two Rails features that we are currently working on are:
|
211
|
+
|
212
|
+
* generator
|
213
|
+
* render extensions
|
214
|
+
|
215
|
+
== Optional Dependencies
|
216
|
+
|
217
|
+
We are currently examining solutions for csv, pdf and charting.
|
218
|
+
|
219
|
+
* Fastercsv # csv
|
220
|
+
* Prawn # pdf
|
221
|
+
* flying saucer # html => PDF - if jRuby available
|
222
|
+
* amcharts # Charting, note that default is built in google charts.
|
223
|
+
|
224
|
+
These will be defined/implemented using DynamicReports plugin API (not implemented yet)
|
225
|
+
Which allows for user defined plugins of arbitrary types beyond html,csv,pdf,xml
|
226
|
+
|
227
|
+
== Contact / Feedback
|
228
|
+
|
229
|
+
If you have any suggestions on improvement please send us an email.
|
230
|
+
|
231
|
+
== Authors (alphabetically)
|
232
|
+
|
233
|
+
Joshua Lippiner (jlippiner@gmail.com)
|
234
|
+
|
235
|
+
Wayne E. Seguin (wayneeseguin@gmail.com, irc: wayneeseguin)
|
236
|
+
|
237
|
+
== Thanks To
|
238
|
+
|
239
|
+
* Daniel Neighman
|
240
|
+
* Kenneth Kalmer & Nic Young
|
241
|
+
* Yehuda Katz
|
242
|
+
|
243
|
+
For their encouragement, feedback and advise.
|
244
|
+
|
245
|
+
== Source
|
246
|
+
http://github.com/wayneeseguin/dynamic_reports
|
247
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{dynamic_reports}
|
5
|
+
s.version = "0.0.4"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Wayne E. Seguin", "Joshua Lippiner"]
|
9
|
+
s.date = %q{2009-07-01}
|
10
|
+
s.description = %q{Dynamic Ruby Reporting Engine with support for Charts.}
|
11
|
+
s.email = %q{wayneeseguin@gmail.com, jlippiner@gmail.com}
|
12
|
+
s.extra_rdoc_files = [
|
13
|
+
"README",
|
14
|
+
"README.rdoc"
|
15
|
+
]
|
16
|
+
s.files = [
|
17
|
+
"HISTORY",
|
18
|
+
"README",
|
19
|
+
"dynamic_reports.gemspec",
|
20
|
+
"lib/dynamic_reports.rb",
|
21
|
+
"lib/dynamic_reports/charts.rb",
|
22
|
+
"lib/dynamic_reports/reports.rb",
|
23
|
+
"lib/dynamic_reports/templates.rb",
|
24
|
+
"lib/dynamic_reports/vendor/google_chart.rb",
|
25
|
+
"lib/dynamic_reports/vendor/google_chart/bar_chart.rb",
|
26
|
+
"lib/dynamic_reports/vendor/google_chart/base.rb",
|
27
|
+
"lib/dynamic_reports/vendor/google_chart/financial_line_chart.rb",
|
28
|
+
"lib/dynamic_reports/vendor/google_chart/line_chart.rb",
|
29
|
+
"lib/dynamic_reports/vendor/google_chart/pie_chart.rb",
|
30
|
+
"lib/dynamic_reports/vendor/google_chart/scatter_chart.rb",
|
31
|
+
"lib/dynamic_reports/vendor/google_chart/venn_diagram.rb",
|
32
|
+
"lib/dynamic_reports/views.rb",
|
33
|
+
"lib/dynamic_reports/views/default_layout.html.erb",
|
34
|
+
"lib/dynamic_reports/views/default_report.html.erb",
|
35
|
+
"lib/dynamic_reports/views/default_report.html.haml"
|
36
|
+
]
|
37
|
+
s.homepage = %q{http://dynamicreports.rubyforge.org/}
|
38
|
+
s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
|
39
|
+
s.require_paths = ["lib"]
|
40
|
+
s.rubyforge_project = %q{dynamicreports}
|
41
|
+
s.rubygems_version = %q{1.3.3}
|
42
|
+
s.summary = %q{Dynamic Ruby Reporting Engine with support for Charts}
|
43
|
+
s.test_files = [
|
44
|
+
"test/dynamic_reports/charts_test.rb",
|
45
|
+
"test/dynamic_reports/reports_test.rb",
|
46
|
+
"test/dynamic_reports/templates_test.rb",
|
47
|
+
"test/dynamic_reports/views_test.rb",
|
48
|
+
"test/dynamic_reports.rb",
|
49
|
+
"test/factories/records.rb",
|
50
|
+
"test/test_helper.rb"
|
51
|
+
]
|
52
|
+
|
53
|
+
if s.respond_to? :specification_version then
|
54
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
55
|
+
s.specification_version = 3
|
56
|
+
|
57
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
58
|
+
else
|
59
|
+
end
|
60
|
+
else
|
61
|
+
end
|
62
|
+
end
|
data/lib/dynamic_reports.rb
CHANGED
@@ -22,7 +22,14 @@ require "dynamic_reports/vendor/google_chart"
|
|
22
22
|
# require "dynamic_reports/rails"
|
23
23
|
# For now placing the code right here:
|
24
24
|
if defined?(Rails)
|
25
|
-
#
|
25
|
+
# ath_to_lib = File.join(Rails.root, "app") #adjust if necessary
|
26
|
+
# path_to_tree = "#{path_to_lib}/reports"
|
27
|
+
# Dir["#{path_to_tree}/**/*.rb"].each { |fn|
|
28
|
+
# fn =~ /^#{Regexp.escape(path_to_lib)}\/(.*)\.rb$/
|
29
|
+
# require $1
|
30
|
+
# }
|
31
|
+
|
32
|
+
# Load all defined reports.
|
26
33
|
# Question: How to get Rails to reload files other than ones matching the requested constant...
|
27
34
|
#Dir.glob("#{File.join(Rails.root, "app", "reports")}/*.rb").each { |file| require file }
|
28
35
|
ActiveSupport::Dependencies.load_paths << File.join(Rails.root, "app", "reports")
|
@@ -44,4 +51,3 @@ if defined?(Rails)
|
|
44
51
|
|
45
52
|
# TODO: Generator
|
46
53
|
end
|
47
|
-
|
@@ -8,7 +8,7 @@ module DynamicReports
|
|
8
8
|
class Report
|
9
9
|
@@default_engine = "erb"
|
10
10
|
|
11
|
-
attr_accessor :name, :title, :sub_title, :columns, :charts, :records, :template, :class_name, :styles
|
11
|
+
attr_accessor :name, :title, :sub_title, :columns, :charts, :records, :template, :class_name, :styles, :links
|
12
12
|
|
13
13
|
# views accessor, array of view paths.
|
14
14
|
def views
|
@@ -24,7 +24,13 @@ module DynamicReports
|
|
24
24
|
# Views setter and accessor.
|
25
25
|
def views(*array)
|
26
26
|
@views ||= ["#{File::dirname(File::expand_path(__FILE__))}/views/"]
|
27
|
-
array
|
27
|
+
unless array.empty?
|
28
|
+
@views.unshift(array)
|
29
|
+
@views.flatten!
|
30
|
+
@views.uniq!
|
31
|
+
else
|
32
|
+
@views
|
33
|
+
end
|
28
34
|
end
|
29
35
|
|
30
36
|
# class level options accessor
|
@@ -100,7 +106,11 @@ module DynamicReports
|
|
100
106
|
# OrdersReport.template # => :orders
|
101
107
|
#
|
102
108
|
def template(value = nil)
|
103
|
-
|
109
|
+
if value
|
110
|
+
@template = value
|
111
|
+
options[:template] = @template
|
112
|
+
end
|
113
|
+
@template ||= nil
|
104
114
|
end
|
105
115
|
|
106
116
|
# Accessor for columns
|
@@ -160,6 +170,50 @@ module DynamicReports
|
|
160
170
|
chart_options = chart_options.shift || {}
|
161
171
|
charts(Chart.configure(name, chart_options, &block))
|
162
172
|
end
|
173
|
+
|
174
|
+
# Return an array of links defined for the report.
|
175
|
+
def links(object=nil)
|
176
|
+
options[:links] ||= []
|
177
|
+
options[:links] << object if object
|
178
|
+
options[:links]
|
179
|
+
end
|
180
|
+
|
181
|
+
# Define a link for the report
|
182
|
+
#
|
183
|
+
# Pass parameters within {}. Parameters are replaced with the row values
|
184
|
+
# from passed records. You do NOT need to include a parameter value as a
|
185
|
+
# report column for it to be used in a link. For example, you might
|
186
|
+
# want to generate a link with an ID field in it but not display that id
|
187
|
+
# in the actual report. Just include {id} to do this.
|
188
|
+
#
|
189
|
+
# Example:
|
190
|
+
#
|
191
|
+
# link :visits, '/reports/{visit}/details?date={recorded_at}'
|
192
|
+
#
|
193
|
+
def link(column, url, link_options=nil)
|
194
|
+
links({:column => column, :url => url, :link_options => link_options})
|
195
|
+
end
|
196
|
+
|
197
|
+
# Define an inline subreport for the report
|
198
|
+
#
|
199
|
+
# Pass parameters within {}. Parameters are replaced with the row values
|
200
|
+
# from passed records. You do NOT need to include a parameter value as a
|
201
|
+
# report column for it to be used in a link. For example, you might
|
202
|
+
# want to generate a subreport with an ID field in it but not display that id
|
203
|
+
# in the actual report. Just include {id} to do this.
|
204
|
+
#
|
205
|
+
# Example:
|
206
|
+
#
|
207
|
+
# subreport :visits, '/reports/{visit}/details?date={recorded_at}'
|
208
|
+
#
|
209
|
+
# The subreport should be created using the same report definition style
|
210
|
+
# that you use for any other report.
|
211
|
+
#
|
212
|
+
def subreport(column, url, link_options=nil)
|
213
|
+
link_options ||= {}
|
214
|
+
link_options.merge!({:class => 'sub_report_link'})
|
215
|
+
links({:column => column, :url => url, :link_options => link_options})
|
216
|
+
end
|
163
217
|
|
164
218
|
# Method for instanciating a report instance on a set of given records.
|
165
219
|
#
|
@@ -177,14 +231,6 @@ module DynamicReports
|
|
177
231
|
def on(records)
|
178
232
|
new(records, @options)
|
179
233
|
end
|
180
|
-
|
181
|
-
#--
|
182
|
-
# Methods for definining a sub report
|
183
|
-
#def link_column
|
184
|
-
#end
|
185
|
-
#def link_rows
|
186
|
-
#end
|
187
|
-
|
188
234
|
end
|
189
235
|
|
190
236
|
# Instantiate the report on a set of records.
|
@@ -201,10 +247,15 @@ module DynamicReports
|
|
201
247
|
def initialize(records, *new_options)
|
202
248
|
new_options = new_options.shift || {}
|
203
249
|
@records = records
|
204
|
-
|
205
|
-
@views
|
206
|
-
@views
|
250
|
+
|
251
|
+
@views = self.class.views
|
252
|
+
@views.unshift(new_options.delete(:views)) if new_options[:views]
|
253
|
+
@views.flatten!
|
254
|
+
@views.uniq!
|
255
|
+
|
256
|
+
@template = self.class.template
|
207
257
|
@template = new_options.delete(:template) if new_options[:template]
|
258
|
+
|
208
259
|
@options = self.class.options.merge!(new_options)
|
209
260
|
@options.each_pair do |key,value|
|
210
261
|
if key == "chart"
|
@@ -233,6 +284,7 @@ module DynamicReports
|
|
233
284
|
options = (options.shift || {}).merge!(@options || {})
|
234
285
|
# todo: if rails is loaded set the default engine: dynamicreports::report.default_engine
|
235
286
|
engine = options.delete(:engine) || @@default_engine
|
287
|
+
options[:template] = self.class.template
|
236
288
|
view.__send__("#{engine}", options)
|
237
289
|
end
|
238
290
|
|
@@ -32,7 +32,7 @@ module DynamicReports
|
|
32
32
|
|
33
33
|
# TODO: Add Report Helpers for injection
|
34
34
|
def titleize(object)
|
35
|
-
object.to_s.split('_').each{ |word| word.capitalize! }.join(' ')
|
35
|
+
object.to_s.split('_').each{ |word| word.capitalize! }.join(' ')
|
36
36
|
end
|
37
37
|
|
38
38
|
def commify(object)
|
@@ -43,9 +43,44 @@ module DynamicReports
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
def linkcheck(record, column_object)
|
47
|
+
val = ''
|
48
|
+
|
49
|
+
if column_object.is_a?(Hash)
|
50
|
+
if column_object.keys.include?(:column)
|
51
|
+
column = column_object[:column]
|
52
|
+
else
|
53
|
+
column = column_object.keys.first # => Josh shortcut :)
|
54
|
+
end
|
55
|
+
else
|
56
|
+
column = column_object
|
57
|
+
end
|
58
|
+
|
59
|
+
report.links.each do |link|
|
60
|
+
if link[:column] == column
|
61
|
+
url = link[:url]
|
62
|
+
url.scan(/\{(\w+)\}/).each do |parameter|
|
63
|
+
parameter = parameter.to_s
|
64
|
+
url = url.gsub("{#{parameter}}", CGI::escape(get_record_value(record, parameter.to_sym).to_s))
|
65
|
+
end
|
66
|
+
|
67
|
+
url_attribute_str = []
|
68
|
+
link[:link_options].keys.each do |key|
|
69
|
+
url_attribute_str << "#{key}='#{link[:link_options][key]}'"
|
70
|
+
end if link[:link_options]
|
71
|
+
|
72
|
+
val = "<a href='#{url}' #{url_attribute_str.join(' ')}>#{get_record_value(record,column)}</a>"
|
73
|
+
break
|
74
|
+
end if link[:column]
|
75
|
+
end if report.links
|
76
|
+
|
77
|
+
val.blank? ? get_record_value(record,column) : val
|
78
|
+
end
|
79
|
+
|
80
|
+
|
46
81
|
def chart_url(chart,report)
|
47
82
|
columns = chart.columns ? chart.columns : report.columns
|
48
|
-
chart_type = chart.type.nil? ? :line : chart.type.to_sym
|
83
|
+
chart_type = chart.type.nil? ? :line : chart.type.to_sym
|
49
84
|
case chart_type
|
50
85
|
when :line
|
51
86
|
Charts.line_chart(chart,columns,report)
|
@@ -62,7 +97,7 @@ module DynamicReports
|
|
62
97
|
end
|
63
98
|
|
64
99
|
private
|
65
|
-
|
100
|
+
|
66
101
|
def render(engine, template, options={}, locals={})
|
67
102
|
# merge app-level options
|
68
103
|
options = self.class.send(engine).merge(options) if self.class.respond_to?(engine)
|
@@ -74,7 +109,7 @@ module DynamicReports
|
|
74
109
|
content_type = options.delete(:content_type)
|
75
110
|
locals = options.delete(:locals) || locals || {}
|
76
111
|
locals.merge!(:report => @report, :options => options || {})
|
77
|
-
|
112
|
+
|
78
113
|
# render template
|
79
114
|
data, options[:filename], options[:line] = lookup_template(engine, template, views, content_type)
|
80
115
|
output = __send__("render_#{engine}", template, data, options, locals)
|
@@ -101,7 +136,7 @@ module DynamicReports
|
|
101
136
|
lookup_template(engine, cached[:template], views, content_type, cached[:filename], cached[:line])
|
102
137
|
else
|
103
138
|
filename = "#{template}.#{content_type}.#{engine}"
|
104
|
-
dir = views.to_a.detect do |view|
|
139
|
+
dir = views.to_a.detect do |view|
|
105
140
|
::File.exists?(::File.join(view, filename))
|
106
141
|
end
|
107
142
|
if dir
|
@@ -172,7 +207,15 @@ module DynamicReports
|
|
172
207
|
require engine.downcase
|
173
208
|
end
|
174
209
|
|
175
|
-
|
176
|
-
|
210
|
+
def get_record_value(record, column)
|
211
|
+
if record.is_a?(Hash)
|
212
|
+
record[column]
|
213
|
+
elsif record.respond_to?(column.to_sym)
|
214
|
+
record.send(column.to_sym)
|
215
|
+
else
|
216
|
+
column
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
177
220
|
end
|
178
221
|
end
|
@@ -1,34 +1,3 @@
|
|
1
|
-
<% if report.class_name.nil? %>
|
2
|
-
<style type="text/css">
|
3
|
-
.dynamic_report .report_title {
|
4
|
-
font-size:16pt;
|
5
|
-
font-weight:bold;
|
6
|
-
margin:10px 0px;
|
7
|
-
}
|
8
|
-
.dynamic_report .report_subtitle {
|
9
|
-
font-size:14pt;
|
10
|
-
color:black;
|
11
|
-
margin:10px 0px;
|
12
|
-
}
|
13
|
-
.dynamic_report table tr th {
|
14
|
-
color: white;
|
15
|
-
background: gray;
|
16
|
-
padding:5px;
|
17
|
-
}
|
18
|
-
.dynamic_report table tr td {
|
19
|
-
border: 1px solid black;
|
20
|
-
padding:3px 15px;
|
21
|
-
}
|
22
|
-
.dynamic_report .report_charts {
|
23
|
-
width:100%;
|
24
|
-
}
|
25
|
-
|
26
|
-
.dynamic_report .report_chart {
|
27
|
-
margin:15px;
|
28
|
-
}
|
29
|
-
</style>
|
30
|
-
<% end %>
|
31
|
-
|
32
1
|
<div id="<%= report.class_name %>" class="dynamic_report">
|
33
2
|
<%= "<div class='report_title'>#{report.title}</div>" if report.title %>
|
34
3
|
<%= "<div class='report_subtitle'>#{report.sub_title}</div>" if report.sub_title %>
|
@@ -36,38 +5,38 @@
|
|
36
5
|
<thead class="report_header">
|
37
6
|
<tr class="report_header_row">
|
38
7
|
<% report.columns.each do |column| %>
|
39
|
-
|
40
|
-
|
41
|
-
|
8
|
+
<th>
|
9
|
+
<% if column.is_a?(Hash) %>
|
10
|
+
<% if column.keys.include?(:heading) %>
|
11
|
+
<%= options[:titleize] ? titleize(column[:heading]) : column[:heading] %>
|
12
|
+
<% else %>
|
13
|
+
<%= options[:titleize] ? titleize(column.values.first) : column.values.first %>
|
14
|
+
<% end %>
|
15
|
+
<% else %>
|
16
|
+
<%= options[:titleize] ? titleize(column) : column %>
|
17
|
+
<% end %>
|
18
|
+
</th>
|
42
19
|
<% end %>
|
43
20
|
</tr>
|
44
21
|
</thead>
|
45
22
|
<tbody class="report_body">
|
46
23
|
<% report.records.each do |record| %>
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
<% else %>
|
55
|
-
<%= column %>
|
56
|
-
<% end %>
|
57
|
-
</td>
|
58
|
-
<% end %>
|
59
|
-
</tr>
|
24
|
+
<tr class="report_row">
|
25
|
+
<% report.columns.each do |column| %>
|
26
|
+
<td>
|
27
|
+
<%= (options[:commas] == true) ? commify(linkcheck(record,column)) : linkcheck(record,column) %>
|
28
|
+
</td>
|
29
|
+
<% end %>
|
30
|
+
</tr>
|
60
31
|
<% end %>
|
61
32
|
</tbody>
|
62
33
|
</table>
|
63
|
-
|
34
|
+
|
64
35
|
<div class="report_charts">
|
65
36
|
<% report.charts.to_a.each do |chart| %>
|
66
|
-
|
67
|
-
|
68
|
-
|
37
|
+
<span class="report_chart">
|
38
|
+
<%= "<img src='#{chart_url(chart,report)}' alt='#{chart.name}'>" %>
|
39
|
+
</span>
|
69
40
|
<% end %>
|
70
41
|
</div>
|
71
|
-
|
72
42
|
</div>
|
73
|
-
|
@@ -1,31 +1,3 @@
|
|
1
|
-
- if report.class_name.nil?
|
2
|
-
%style{type => "text/css"}
|
3
|
-
\.dynamic_report .report_title {
|
4
|
-
font-size:16pt;
|
5
|
-
font-weight:bold;
|
6
|
-
margin:10px 0px;
|
7
|
-
}
|
8
|
-
\.dynamic_report .report_subtitle {
|
9
|
-
font-size:14pt;
|
10
|
-
color:black;
|
11
|
-
margin:10px 0px;
|
12
|
-
}
|
13
|
-
\.dynamic_report table tr th {
|
14
|
-
color: white;
|
15
|
-
background: gray;
|
16
|
-
padding:5px;
|
17
|
-
}
|
18
|
-
\.dynamic_report table tr td {
|
19
|
-
border: 1px solid black;
|
20
|
-
padding:3px 15px;
|
21
|
-
}
|
22
|
-
\.dynamic_report .report_charts {
|
23
|
-
width:100%;
|
24
|
-
}
|
25
|
-
\.dynamic_report .report_chart {
|
26
|
-
margin:15px;
|
27
|
-
}
|
28
|
-
|
29
1
|
.dynamic_report{ :id => report.class_name }
|
30
2
|
- if report.title
|
31
3
|
%h2.report_title
|
@@ -40,18 +12,19 @@
|
|
40
12
|
%tr.report_header_row
|
41
13
|
- report.columns.each do |column|
|
42
14
|
%th
|
43
|
-
|
15
|
+
- if column.is_a?(Hash)
|
16
|
+
- if column.keys.include?(:heading)
|
17
|
+
= options[:titleize] ? titleize(column[:heading]) : column[:heading]
|
18
|
+
-else
|
19
|
+
= options[:titleize] ? titleize(column.values.first) : column.values.first
|
20
|
+
-else
|
21
|
+
= options[:titleize] ? titleize(column) : column
|
44
22
|
%tbody.report_body
|
45
23
|
- report.records.each do |record|
|
46
24
|
%tr.report_row
|
47
25
|
- report.columns.each do |column|
|
48
26
|
%td
|
49
|
-
|
50
|
-
= (options[:commas] == true) ? commify(record[column]) : record[column]
|
51
|
-
- elsif record.respond_to?(column.to_sym)
|
52
|
-
= (options[:commas] == true) ? commify(record.send(column.to_sym)) : record.send(column.to_sym)
|
53
|
-
- else
|
54
|
-
= column
|
27
|
+
= (options[:commas] == true) ? commify(linkcheck(record,column)) : linkcheck(record,column)
|
55
28
|
|
56
29
|
- if report.charts && report.charts.class === Hash
|
57
30
|
- report.charts.each_pair do |name, chart|
|
@@ -59,4 +32,3 @@
|
|
59
32
|
%h2
|
60
33
|
= name
|
61
34
|
%img{:src => chart_url(chart), :alt => name}
|
62
|
-
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "rubygems"
|
3
|
+
require "test/unit/testsuite"
|
4
|
+
require "test/unit/ui/console/testrunner"
|
5
|
+
#require "test/unit/color"
|
6
|
+
require "shoulda"
|
7
|
+
require "zentest"
|
8
|
+
|
9
|
+
# Libraries
|
10
|
+
require "dynamic_reports"
|
11
|
+
require "test/test_helper"
|
12
|
+
|
13
|
+
# Test files.
|
14
|
+
require "test/dynamic_reports/charts_test"
|
15
|
+
require "test/dynamic_reports/reports_test"
|
16
|
+
require "test/dynamic_reports/views_test"
|
17
|
+
|
18
|
+
require "test/unit"
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class ChartsTest < Test::Unit::TestCase
|
2
|
+
context "charts" do
|
3
|
+
setup do
|
4
|
+
class TheReport < DynamicReports::Report
|
5
|
+
chart :the_chart_name, :an => "option", :another => "option" do
|
6
|
+
title "awesome report!"
|
7
|
+
type :svg
|
8
|
+
height "350"
|
9
|
+
width "250"
|
10
|
+
columns :pageviews
|
11
|
+
label_column "created_at"
|
12
|
+
end
|
13
|
+
chart :the_other_chart_name do
|
14
|
+
title "Some other chart"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
should "allow specification of options to the chart beyond it's attributes." do
|
20
|
+
hash = {
|
21
|
+
:name => :the_chart_name,
|
22
|
+
:an => "option",
|
23
|
+
:type => :svg,
|
24
|
+
:another => "option",
|
25
|
+
:title=>"awesome report!",
|
26
|
+
:height=>"350",
|
27
|
+
:width=>"250",
|
28
|
+
:columns=>[:pageviews],
|
29
|
+
:label_column => "created_at"
|
30
|
+
}
|
31
|
+
assert_equal hash, TheReport.chart_with_name(:the_chart_name).options
|
32
|
+
end
|
33
|
+
|
34
|
+
should "allow setting their name" do
|
35
|
+
assert_equal :the_chart_name, TheReport.chart_with_name(:the_chart_name).name
|
36
|
+
end
|
37
|
+
|
38
|
+
should "allow setting their title" do
|
39
|
+
assert_equal "awesome report!", TheReport.chart_with_name(:the_chart_name).title
|
40
|
+
end
|
41
|
+
|
42
|
+
should "allow setting their type" do
|
43
|
+
assert_equal :svg, TheReport.chart_with_name(:the_chart_name).type
|
44
|
+
end
|
45
|
+
|
46
|
+
should "allow setting their width" do
|
47
|
+
assert_equal "250" ,TheReport.chart_with_name(:the_chart_name).width
|
48
|
+
end
|
49
|
+
|
50
|
+
should "allow setting their height" do
|
51
|
+
assert_equal "350", TheReport.chart_with_name(:the_chart_name).height
|
52
|
+
end
|
53
|
+
|
54
|
+
should "allow definition of multiple charts" do
|
55
|
+
#require "ruby-debug" ; debugger
|
56
|
+
assert_contains TheReport.charts[0].name, :the_chart_name
|
57
|
+
assert_contains TheReport.charts[1].name, :the_other_chart_name
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
class ReportsTest < Test::Unit::TestCase
|
2
|
+
context "a report" do
|
3
|
+
|
4
|
+
setup do
|
5
|
+
class TheReport < DynamicReports::Report
|
6
|
+
name "The Report!"
|
7
|
+
title "Daily Report"
|
8
|
+
sub_title "Happens every day, ya!"
|
9
|
+
columns :recorded_at, :viewed_on, :pageviews_count, :visits_count, :conversions_count
|
10
|
+
|
11
|
+
chart :visits do
|
12
|
+
title "testing chart"
|
13
|
+
columns :visits
|
14
|
+
type "line"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@array_records = DynamicReports::Test::ArrayRecords.generate(TheReport, :count => 10)
|
18
|
+
@object_records = DynamicReports::Test::ObjectRecords.generate(TheReport, :count => 10)
|
19
|
+
end
|
20
|
+
|
21
|
+
should "allow setting the title of a report" do
|
22
|
+
assert_equal "Daily Report", TheReport.title
|
23
|
+
end
|
24
|
+
|
25
|
+
should "allow setting the sub title of a report" do
|
26
|
+
assert_equal "Happens every day, ya!", TheReport.sub_title
|
27
|
+
end
|
28
|
+
|
29
|
+
should "allow setting the columns to report on" do
|
30
|
+
assert_equal [:recorded_at, :viewed_on, :pageviews_count, :visits_count, :conversions_count], TheReport.columns
|
31
|
+
end
|
32
|
+
|
33
|
+
should "return an instantiated report .on is called" do
|
34
|
+
assert_kind_of DynamicReports::Report,
|
35
|
+
TheReport.on(@array_records)
|
36
|
+
end
|
37
|
+
|
38
|
+
should "An instantiated report should return html table report when to_html is called" do
|
39
|
+
assert_match(/<table class="report"/, TheReport.on(@array_records).to_html)
|
40
|
+
end
|
41
|
+
|
42
|
+
should "An instantiated report should contain the rendered chart that was defined" do
|
43
|
+
assert_match(/class="report_charts"/, TheReport.on(@array_records).to_html)
|
44
|
+
end
|
45
|
+
|
46
|
+
context "Report with templates and views specified" do
|
47
|
+
setup do
|
48
|
+
class SpecificTemplateReport < DynamicReports::Report
|
49
|
+
name "A report with specified template!"
|
50
|
+
title "Specify Template Report"
|
51
|
+
sub_title "template is 'other_template'"
|
52
|
+
columns :recorded_at, :viewed_on, :pageviews_count, :visits_count, :conversions_count
|
53
|
+
template :specific_template
|
54
|
+
views "#{File::dirname(File::expand_path(__FILE__))}/views/"
|
55
|
+
end
|
56
|
+
@array_records = DynamicReports::Test::ArrayRecords.generate(SpecificTemplateReport, :count => 10)
|
57
|
+
@object_records = DynamicReports::Test::ObjectRecords.generate(SpecificTemplateReport, :count => 10)
|
58
|
+
end
|
59
|
+
|
60
|
+
should "allow setting of the views directories" do
|
61
|
+
assert_contains SpecificTemplateReport.views,
|
62
|
+
"#{File::dirname(File::expand_path(__FILE__))}/views/"
|
63
|
+
end
|
64
|
+
|
65
|
+
should "the instance should have the same views as the class" do
|
66
|
+
assert_contains SpecificTemplateReport.on(@array_records).views,
|
67
|
+
"#{File::dirname(File::expand_path(__FILE__))}/views/"
|
68
|
+
end
|
69
|
+
|
70
|
+
should "render with the specified template, from the specified views directory" do
|
71
|
+
assert_equal "This is the specified template!",
|
72
|
+
SpecificTemplateReport.on(@array_records).to_html.strip
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
File without changes
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require "ostruct"
|
2
|
+
|
3
|
+
module DynamicReports
|
4
|
+
module Test
|
5
|
+
|
6
|
+
class ArrayRecords
|
7
|
+
def self.generate(report, *options)
|
8
|
+
records = []
|
9
|
+
options = options.shift || {}
|
10
|
+
(0..(options[:count].to_i)).each do |index|
|
11
|
+
hash = {}
|
12
|
+
report.columns.each do |column|
|
13
|
+
hash[column.to_s] =
|
14
|
+
case column.to_s
|
15
|
+
when /_at$/
|
16
|
+
(DateTime.now-100)+index
|
17
|
+
when /_on$/
|
18
|
+
(Date.today-100)+index
|
19
|
+
when /_id$/,/_count$/
|
20
|
+
rand(10000)
|
21
|
+
else
|
22
|
+
column
|
23
|
+
end
|
24
|
+
end
|
25
|
+
records << hash
|
26
|
+
end
|
27
|
+
records
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class ObjectRecords
|
32
|
+
def self.generate(report,*options)
|
33
|
+
records = []
|
34
|
+
options = options.shift || {}
|
35
|
+
(0..(options[:count].to_i)).each do |index|
|
36
|
+
object = OpenStruct.new(report.columns)
|
37
|
+
report.columns.each do |column|
|
38
|
+
value = case column.to_s
|
39
|
+
when /_at$/
|
40
|
+
(DateTime.now-100)+index
|
41
|
+
when /_on$/
|
42
|
+
(Date.today-100)+index
|
43
|
+
when /_id$/,/_count$/
|
44
|
+
rand(10000)
|
45
|
+
else
|
46
|
+
column
|
47
|
+
end
|
48
|
+
|
49
|
+
object.send(column.to_sym, value)
|
50
|
+
|
51
|
+
records << object
|
52
|
+
end
|
53
|
+
records
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class ARRecords
|
59
|
+
def self.generate(*options)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
metadata
CHANGED
@@ -1,33 +1,37 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dynamic_reports
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Wayne E. Seguin
|
7
|
+
- Wayne E. Seguin
|
8
|
+
- Joshua Lippiner
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
12
|
|
12
|
-
date: 2009-
|
13
|
+
date: 2009-07-01 00:00:00 -04:00
|
13
14
|
default_executable:
|
14
15
|
dependencies: []
|
15
16
|
|
16
|
-
description: Dynamic Ruby Reporting Engine with support for Charts
|
17
|
+
description: Dynamic Ruby Reporting Engine with support for Charts.
|
17
18
|
email: wayneeseguin@gmail.com, jlippiner@gmail.com
|
18
19
|
executables: []
|
19
20
|
|
20
21
|
extensions: []
|
21
22
|
|
22
|
-
extra_rdoc_files:
|
23
|
-
|
23
|
+
extra_rdoc_files:
|
24
|
+
- README
|
25
|
+
- README.rdoc
|
24
26
|
files:
|
25
27
|
- HISTORY
|
26
28
|
- README
|
27
|
-
- gemspec
|
29
|
+
- dynamic_reports.gemspec
|
30
|
+
- lib/dynamic_reports.rb
|
28
31
|
- lib/dynamic_reports/charts.rb
|
29
32
|
- lib/dynamic_reports/reports.rb
|
30
33
|
- lib/dynamic_reports/templates.rb
|
34
|
+
- lib/dynamic_reports/vendor/google_chart.rb
|
31
35
|
- lib/dynamic_reports/vendor/google_chart/bar_chart.rb
|
32
36
|
- lib/dynamic_reports/vendor/google_chart/base.rb
|
33
37
|
- lib/dynamic_reports/vendor/google_chart/financial_line_chart.rb
|
@@ -35,19 +39,19 @@ files:
|
|
35
39
|
- lib/dynamic_reports/vendor/google_chart/pie_chart.rb
|
36
40
|
- lib/dynamic_reports/vendor/google_chart/scatter_chart.rb
|
37
41
|
- lib/dynamic_reports/vendor/google_chart/venn_diagram.rb
|
38
|
-
- lib/dynamic_reports/
|
42
|
+
- lib/dynamic_reports/views.rb
|
39
43
|
- lib/dynamic_reports/views/default_layout.html.erb
|
40
44
|
- lib/dynamic_reports/views/default_report.html.erb
|
41
45
|
- lib/dynamic_reports/views/default_report.html.haml
|
42
|
-
-
|
43
|
-
- lib/dynamic_reports.rb
|
46
|
+
- README.rdoc
|
44
47
|
has_rdoc: true
|
45
|
-
homepage: http://
|
48
|
+
homepage: http://dynamicreports.rubyforge.org/
|
46
49
|
licenses: []
|
47
50
|
|
48
51
|
post_install_message:
|
49
|
-
rdoc_options:
|
50
|
-
|
52
|
+
rdoc_options:
|
53
|
+
- --inline-source
|
54
|
+
- --charset=UTF-8
|
51
55
|
require_paths:
|
52
56
|
- lib
|
53
57
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -64,10 +68,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
68
|
version:
|
65
69
|
requirements: []
|
66
70
|
|
67
|
-
rubyforge_project:
|
68
|
-
rubygems_version: 1.3.
|
71
|
+
rubyforge_project: dynamicreports
|
72
|
+
rubygems_version: 1.3.4
|
69
73
|
signing_key:
|
70
74
|
specification_version: 3
|
71
|
-
summary:
|
72
|
-
test_files:
|
73
|
-
|
75
|
+
summary: Dynamic Ruby Reporting Engine with support for Charts
|
76
|
+
test_files:
|
77
|
+
- test/dynamic_reports/charts_test.rb
|
78
|
+
- test/dynamic_reports/reports_test.rb
|
79
|
+
- test/dynamic_reports/templates_test.rb
|
80
|
+
- test/dynamic_reports/views_test.rb
|
81
|
+
- test/dynamic_reports.rb
|
82
|
+
- test/factories/records.rb
|
83
|
+
- test/test_helper.rb
|
data/gemspec.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require "rubygems"
|
2
|
-
|
3
|
-
library="dynamic_reports"
|
4
|
-
version="0.0.1"
|
5
|
-
|
6
|
-
Gem::Specification::new do |spec|
|
7
|
-
$VERBOSE = nil
|
8
|
-
spec.name = library
|
9
|
-
spec.summary = library
|
10
|
-
spec.version = version
|
11
|
-
spec.description = "Dynamic Ruby Reporting Engine with support for Charts"
|
12
|
-
spec.platform = Gem::Platform::RUBY
|
13
|
-
spec.files = ["HISTORY", "README", "gemspec.rb", Dir::glob("lib/**/**")].flatten
|
14
|
-
spec.executables = Dir::glob("bin/*").map{ |script| File::basename script }
|
15
|
-
spec.require_path = "lib"
|
16
|
-
spec.has_rdoc = File::exist?("doc")
|
17
|
-
spec.author = "Wayne E. Seguin & Joshua Lippiner"
|
18
|
-
spec.email = "wayneeseguin@gmail.com, jlippiner@gmail.com"
|
19
|
-
spec.homepage = "http://github.com/wayneeseguin/direct_reports"
|
20
|
-
# spec.test_suite_file = "test/#{library}.rb" if File::directory?("test")
|
21
|
-
#spec.add_dependency "", ">= 0.0"
|
22
|
-
spec.extensions << "extconf.rb" if File::exists?("extconf.rb")
|
23
|
-
spec.rubyforge_project = library
|
24
|
-
end
|