rgviz-rails 0.43 → 0.44

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/README.rdoc ADDED
@@ -0,0 +1,101 @@
1
+ == Rgviz-rails
2
+
3
+ This library makes it easy to implement a Visualization data source so that you can easily chart or visualize your data from ActiveRecord[http://ar.rubyonrails.org/] models. The library implements the {Google Visualization API wire protocol}[http://code.google.com/apis/visualization/documentation/dev/implementing_data_source.html].
4
+
5
+ It also allows you to {render the visualizations in a view template}[https://github.com/asterite/rgviz-rails/wiki/Showing-a-visualization-in-a-view] in a very simple but powerful way.
6
+
7
+ This library is built on top of rgviz[https://github.com/asterite/rgviz].
8
+
9
+ === Installation
10
+
11
+ gem install rgviz-rails
12
+
13
+ In your environment.rb
14
+
15
+ config.gem "rgviz-rails", :lib => 'rgviz_rails'
16
+
17
+ === Usage
18
+
19
+ To make a method in your controller be a visualization API endpoint:
20
+
21
+ class VizController < ApplicationController
22
+
23
+ def person
24
+ # Person is an ActiveRecord::Base class
25
+ render :rgviz => Person
26
+ end
27
+
28
+ end
29
+
30
+ So for example if +Person+ has +name+ and +age+, pointing your browser to:
31
+
32
+ http://localhost:3000/viz/person?select name where age > 20 limit 5
33
+
34
+ would render the necessary javascript code that implements the Google Visualization API wire protocol.
35
+
36
+ === Extensions
37
+
38
+ To enable the extensions defined by rgviz you need to specify it in the render method:
39
+
40
+ render :rgviz => Person, :extensions => true
41
+
42
+ === Associations
43
+
44
+ If you want to filter, order by or group by columns that are in a model's association you can use underscores. This is better understood with an example:
45
+
46
+ class Person < ActiveRecord::Base
47
+ belongs_to :city
48
+ end
49
+
50
+ class City < ActiveRecord::Base
51
+ belongs_to :country
52
+ end
53
+
54
+ class Country < ActiveRecord::Base
55
+ end
56
+
57
+ To select the name of the city each person belongs to:
58
+
59
+ select city_name
60
+
61
+ To select the name of the country of the city each person belongs to:
62
+
63
+ select city_country_name
64
+
65
+ A slightly more complex example:
66
+
67
+ select avg(age) where city_country_name = 'Argentina' group by city_name
68
+
69
+ The library will make it in just one query, writing all the SQL joins for you.
70
+
71
+ === Extra conditions
72
+
73
+ Sometimes you want to limit your results the query will work with. You can do it like this:
74
+
75
+ render :rgviz => Person, :conditions => ['age > ?', 20]
76
+
77
+ Or also:
78
+
79
+ render :rgviz => Person, :conditions => 'age > 20'
80
+
81
+ === Preprocessing
82
+
83
+ If you need to tweak a result before returning it, just include a block:
84
+
85
+ render :rgviz => Person do |table|
86
+ # Modify the Rgviz::Table object
87
+ end
88
+
89
+ === Showing a visualization in a view
90
+
91
+ You can invoke the rgviz method in your views. {Read more about this}[https://github.com/asterite/rgviz-rails/wiki/Showing-a-visualization-in-a-view].
92
+
93
+ You can always do it the {old way}[http://code.google.com/apis/visualization/documentation/using_overview.html]. {Read more about this}
94
+
95
+ === Current Limitations
96
+ * The *format* clause is ignored (If someone knows of a working icu library for ruby, please tell me)
97
+ * Only supports MySQL, PostgreSQL and SQLite adapters
98
+ * These scalar functions are not supported for SQLite: *millisecond*, *quarter*
99
+ * These scalar functions are not supported for MySQL: *millisecond*
100
+ * The function *toDate* doesn't accept a number as its argument
101
+ * The *tsv* output format is not supported
data/lib/rgviz_rails.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'rgviz_rails/init.rb'
1
2
  require 'rgviz_rails/executor.rb'
2
3
  require 'rgviz_rails/js_renderer.rb'
3
4
  require 'rgviz_rails/tqx.rb'
@@ -517,32 +517,16 @@ module Rgviz
517
517
  col = klass.send(:columns).select{|x| x.name == name}.first
518
518
  return [klass, col, joins] if col
519
519
 
520
- offset = 0
521
- while true
522
- idx = name.index '_', offset
523
- if not idx
524
- # Try to see if the name is an association, and refer to the id
525
- assoc = klass.send :reflect_on_association, name.to_sym
526
- if assoc
527
- col = klass.send(:columns).select{|x| x.name == assoc.association_foreign_key}.first
528
- return [klass, col, joins] if col
529
- end
530
- return nil
531
- end
532
-
533
- before = name[0 ... idx]
534
- new_name = name[idx + 1 .. -1]
535
-
536
- assoc = klass.send :reflect_on_association, before.to_sym
537
- if assoc
538
- name = new_name
539
- klass = assoc.klass
540
- joins << assoc
541
- break
542
- end
543
-
544
- offset = idx + 1
545
- end
520
+ idx = name.index '_'
521
+ return nil if not idx
522
+
523
+ before = name[0 ... idx]
524
+ name = name[idx + 1 .. -1]
525
+
526
+ assoc = klass.send :reflect_on_association, before.to_sym
527
+ raise "Unknown association #{before}" unless assoc
528
+ klass = assoc.klass
529
+ joins << assoc
546
530
  end
547
531
  end
548
532
 
@@ -2,63 +2,75 @@ require "rgviz_rails/view_helper"
2
2
  # includes the view helper to ActionView::Base
3
3
  ActionView::Base.send(:include, Rgviz::ViewHelper)
4
4
 
5
- config.after_initialize do
6
- class ::ActionController::Base
7
- alias_method :original_render, :render
8
- def render(*args, &block)
5
+ def _define_rgviz_class
6
+ ::ActionController::Base.module_eval do
7
+ def render_with_rgviz(*args, &block)
9
8
  if args.length == 1 && args[0].kind_of?(Hash)
10
- hash = args.first
9
+ hash = args.first
11
10
  case hash[:rgviz]
12
- when nil then original_render *args, &block
11
+ when nil then render_without_rgviz *args, &block
13
12
  else
14
13
  model = hash[:rgviz]
15
14
  conditions = hash[:conditions]
16
15
  extensions = hash[:extensions]
17
16
  query = params[:tq]
18
17
  tqx = params[:tqx] || ''
19
-
18
+
20
19
  tqx = Rgviz::Tqx.parse(tqx)
21
-
20
+
22
21
  begin
23
22
  executor = Rgviz::Executor.new model, query
24
23
  options = {}
25
24
  options[:conditions] = conditions if conditions
26
25
  options[:extensions] = extensions if extensions
27
26
  table = executor.execute options
28
-
27
+
29
28
  yield table if block_given?
30
-
29
+
31
30
  case tqx['out']
32
31
  when 'json'
33
- original_render :text => Rgviz::JsRenderer.render(table, tqx)
32
+ render_without_rgviz :text => Rgviz::JsRenderer.render(table, tqx)
34
33
  when 'html'
35
- original_render :text => Rgviz::HtmlRenderer.render(table)
34
+ render_without_rgviz :text => Rgviz::HtmlRenderer.render(table)
36
35
  when 'csv'
37
36
  csv_output = Rgviz::CsvRenderer.render(table)
38
37
  if tqx['outFileName']
39
38
  send_data csv_output, :filename => tqx['outFileName'], :type => 'text/csv'
40
39
  else
41
- original_render :text => csv_output
40
+ render_without_rgviz :text => csv_output
42
41
  end
43
42
  else
44
- original_render :text => Rgviz::JsRenderer.render_error('not_supported', "Unsupported output type: #{out}", tqx)
43
+ render_without_rgviz :text => Rgviz::JsRenderer.render_error('not_supported', "Unsupported output type: #{out}", tqx)
45
44
  end
46
45
  rescue ParseException => e
47
46
  case tqx['out']
48
47
  when 'json'
49
- original_render :text => Rgviz::JsRenderer.render_error('invalid_query', e.message, tqx)
48
+ render_without_rgviz :text => Rgviz::JsRenderer.render_error('invalid_query', e.message, tqx)
50
49
  when 'html'
51
- original_render :text => "<b>Error:</b> #{e.message}"
50
+ render_without_rgviz :text => "<b>Error:</b> #{e.message}"
52
51
  when 'csv'
53
- original_render :text => "Error: #{e.message}"
52
+ render_without_rgviz :text => "Error: #{e.message}"
54
53
  else
55
- original_render :text => "<b>Unsupported output type:</b> #{out}"
54
+ render_without_rgviz :text => "<b>Unsupported output type:</b> #{out}"
56
55
  end
57
56
  end
58
57
  end
59
58
  else
60
- original_render *args, &block
59
+ render_without_rgviz *args, &block
61
60
  end
62
61
  end
62
+ alias_method_chain :render, :rgviz
63
+ end
64
+ end
65
+
66
+ if Rails::VERSION::MAJOR == 2
67
+ config.after_initialize do
68
+ _define_rgviz_class
69
+ end
70
+ else
71
+ class Railtie < Rails::Railtie
72
+ initializer "define rgviz class" do
73
+ _define_rgviz_class
74
+ end
63
75
  end
64
76
  end
@@ -6,7 +6,7 @@ module Rgviz
6
6
  i = 0
7
7
  opts.each do |key, value|
8
8
  key = key.to_s.gsub('"', '\"')
9
-
9
+
10
10
  @s << ',' if i > 0
11
11
  @s << "\"#{key}\":"
12
12
  if special_keys.include?(key) || !value.kind_of?(String)
@@ -19,9 +19,9 @@ module Rgviz
19
19
  end
20
20
  @s << '}'
21
21
  end
22
-
22
+
23
23
  options = options.with_indifferent_access
24
-
24
+
25
25
  id = options[:id]
26
26
  kind = options[:kind]
27
27
  url = options[:url]
@@ -30,74 +30,74 @@ module Rgviz
30
30
  html = options[:html] || {}
31
31
  hidden = options[:hidden]
32
32
  extensions = options[:extensions]
33
-
33
+
34
34
  rgviz_events, google_events = events.partition{|x| x.to_s.start_with? 'rgviz'}
35
35
  rgviz_events = rgviz_events.inject(Hash.new){|h, y| h[y[0]] = y[1]; h}
36
36
  rgviz_events = rgviz_events.with_indifferent_access
37
-
37
+
38
38
  html_prefix = (options[:html_prefix] || 'html').to_s
39
39
  js_prefix = (options[:js_prefix] || 'js').to_s
40
40
  param_prefix = (options[:param_prefix] || 'param').to_s
41
-
41
+
42
42
  html_prefix += '_'
43
43
  js_prefix += '_'
44
44
  param_prefix += '_'
45
-
45
+
46
46
  debug = options[:debug]
47
47
  opts = options[:options] || {}
48
48
  opts[:width] = 640 unless opts[:width]
49
49
  opts[:height] = 480 unless opts[:height]
50
-
50
+
51
51
  params = []
52
52
  uses_rgviz_get_value = false
53
53
  uses_rgviz_append = false
54
-
54
+
55
55
  visitor = MagicNamesVisitor.new(html_prefix, js_prefix, param_prefix)
56
-
56
+
57
57
  special_keys = []
58
-
58
+
59
59
  opts.each do |key, value|
60
60
  next unless value.kind_of?(String)
61
-
61
+
62
62
  source = visitor.get_source(value, false)
63
63
  next unless source[:source]
64
-
64
+
65
65
  special_keys << key
66
-
66
+
67
67
  case source[:source]
68
68
  when :html
69
- opts[key] = "rgviz_get_value('#{source[:id]}')"
70
- uses_rgviz_get_value = true
69
+ opts[key] = "rgviz_get_value('#{source[:id]}')"
70
+ uses_rgviz_get_value = true
71
71
  when :js
72
72
  opts[key] = "#{source[:id]}()"
73
73
  when :param
74
74
  opts[key] = "param_#{source[:id]}"
75
75
  params << source[:id].to_i unless params.include?(source[:id])
76
- end
76
+ end
77
77
  end
78
-
78
+
79
79
  opts = opts_to_json(opts, special_keys)
80
-
80
+
81
81
  raise "Must specify an :id" unless id
82
82
  raise "Must specify a :kind" unless kind
83
83
  raise "Must specify a :url" unless url
84
-
84
+
85
85
  url = url_for url
86
-
86
+
87
87
  # Parse the query
88
88
  query = Parser.parse query, :extensions => extensions
89
-
89
+
90
90
  # And replace the html_ and javascript_ magic names
91
91
  query.accept visitor
92
92
  query_builder = visitor.query_builder
93
93
  query_builder_var = visitor.query_builder_var
94
-
94
+
95
95
  uses_rgviz_get_value |= visitor.uses_rgviz_get_value?
96
96
  uses_rgviz_append |= visitor.uses_rgviz_append?
97
-
97
+
98
98
  visitor.params.each{|p| params << p unless params.include?(p)}
99
99
  params = params.sort!.map{|i| "param_#{i}"}
100
-
100
+
101
101
  out = ''
102
102
 
103
103
  # Output the google jsapi tag the first time
@@ -107,15 +107,15 @@ module Rgviz
107
107
  end
108
108
  # Now the real script
109
109
  out << "<script type=\"text/javascript\">\n"
110
-
110
+
111
111
  # Define a function to get the value of an html element
112
- if uses_rgviz_get_value && !@defined_rgviz_get_value
112
+ if uses_rgviz_get_value && !@defined_rgviz_get_value
113
113
  out << "function rgviz_get_value(id) {\n"
114
114
  out << "var e = document.getElementById(id);\n"
115
115
  out << "var n = e.tagName.toLowerCase();\n"
116
116
  out << "var s = null;\n"
117
117
  out << "if (n == 'select' && e.multiple) {\n"
118
- out << "var s = [];\n"
118
+ out << "var s = [];\n"
119
119
  out << "var o = e.options;\n"
120
120
  out << "for(var i = 0; i < o.length; i++)\n"
121
121
  out << "if (o[i].selected) s.push(o[i].value);\n"
@@ -128,7 +128,7 @@ module Rgviz
128
128
  out << "}\n"
129
129
  @defined_rgviz_get_value = true
130
130
  end
131
-
131
+
132
132
  # Define a function to append the value of a magic something
133
133
  if uses_rgviz_append && !@defined_rgviz_append
134
134
  out << "function rgviz_append(s, b, a) {\n"
@@ -147,27 +147,27 @@ module Rgviz
147
147
  out << "}\n"
148
148
  @defined_rgviz_append = true
149
149
  end
150
-
150
+
151
151
  # Load visualizations and the package, if not already loaded
152
- pack = kind.downcase
152
+ pack = kind.downcase
153
153
  @packages ||= []
154
154
  unless @packages.include?(pack)
155
155
  out << "google.load(\"visualization\", \"1\", {'packages':['#{pack}']});\n"
156
156
  @packages << pack
157
157
  end
158
-
158
+
159
159
  callback = "rgviz_draw_#{id}"
160
-
160
+
161
161
  # Set the callback if the function doesn't have params and if the
162
162
  # user didn't request to hide the visualization
163
163
  if !hidden && params.empty?
164
164
  out << "google.setOnLoadCallback(#{callback});\n"
165
165
  end
166
-
166
+
167
167
  # Define the visualization var and data
168
168
  out << "var rgviz_#{id} = null;\n"
169
169
  out << "var rgviz_#{id}_data = null;\n"
170
-
170
+
171
171
  # And define the callback
172
172
  out << "function #{callback}(#{params.join(', ')}) {\n"
173
173
  out << "#{rgviz_events[:rgviz_start]}('#{id}');\n" if rgviz_events[:rgviz_start]
@@ -185,24 +185,28 @@ module Rgviz
185
185
  out << "#{rgviz_events[:rgviz_end]}('#{id}');\n" if rgviz_events[:rgviz_end]
186
186
  out << "});\n"
187
187
  out << "}\n"
188
-
188
+
189
189
  out << "</script>\n"
190
-
190
+
191
191
  # Write the div
192
192
  out << "<div id=\"#{id}\""
193
193
  html.each do |key, value|
194
194
  out << " #{key}=\"#{h value}\""
195
195
  end
196
196
  out << "></div>\n"
197
-
197
+
198
198
  @first_time = 0
199
-
200
- out
199
+
200
+ if defined? :raw
201
+ raw out
202
+ else
203
+ out
204
+ end
201
205
  end
202
-
206
+
203
207
  module_function :rgviz
204
208
  end
205
-
209
+
206
210
  class MagicNamesVisitor < Visitor
207
211
  def initialize(html_prefix, js_prefix, param_prefix)
208
212
  @html_prefix = html_prefix
@@ -211,27 +215,27 @@ module Rgviz
211
215
  @s = ''
212
216
  @params = []
213
217
  end
214
-
218
+
215
219
  def query_builder
216
220
  @s.strip
217
221
  end
218
-
222
+
219
223
  def query_builder_var
220
224
  'q'
221
225
  end
222
-
226
+
223
227
  def params
224
228
  @params
225
229
  end
226
-
230
+
227
231
  def uses_rgviz_get_value?
228
232
  @uses_rgviz_get_value
229
233
  end
230
-
234
+
231
235
  def uses_rgviz_append?
232
236
  @uses_rgviz_append
233
237
  end
234
-
238
+
235
239
  def visit_query(node)
236
240
  @s << "var q = '"
237
241
  node.select.accept self if node.select
@@ -241,20 +245,20 @@ module Rgviz
241
245
  node.order_by.accept self if node.order_by
242
246
  @s << "limit #{node.limit} " if node.limit
243
247
  @s << "offset #{node.offset} " if node.offset
244
- if node.labels
248
+ if node.labels
245
249
  @s << "label "
246
250
  node.labels.each_with_index do |l, i|
247
- @s << ', ' if i > 0
251
+ @s << ', ' if i > 0
248
252
  l.accept self
249
253
  end
250
- end
254
+ end
251
255
  if node.formats
252
256
  @s << "format "
253
257
  node.formats.each_with_index do |f, i|
254
- @s << ', ' if i > 0
258
+ @s << ', ' if i > 0
255
259
  f.accept self
256
260
  end
257
- end
261
+ end
258
262
  if node.options
259
263
  @s << "options "
260
264
  @s << "no_values " if node.options.no_values
@@ -263,35 +267,35 @@ module Rgviz
263
267
  @s << "';\n"
264
268
  false
265
269
  end
266
-
270
+
267
271
  def visit_select(node)
268
272
  @s << "select ";
269
273
  print_columns node
270
274
  @s << " "
271
275
  false
272
276
  end
273
-
277
+
274
278
  def visit_where(node)
275
279
  @s << "where "
276
280
  node.expression.accept self
277
281
  @s << " "
278
282
  false
279
283
  end
280
-
284
+
281
285
  def visit_group_by(node)
282
286
  @s << "group by "
283
287
  print_columns node
284
288
  @s << " "
285
289
  false
286
290
  end
287
-
291
+
288
292
  def visit_pivot(node)
289
293
  @s << "pivot "
290
294
  print_columns node
291
295
  @s << " "
292
296
  false
293
297
  end
294
-
298
+
295
299
  def visit_order_by(node)
296
300
  @s << "order by "
297
301
  node.sorts.each_with_index do |s, i|
@@ -303,7 +307,7 @@ module Rgviz
303
307
  @s << " "
304
308
  false
305
309
  end
306
-
310
+
307
311
  def visit_label(node)
308
312
  node.column.accept self
309
313
  @s << ' '
@@ -315,7 +319,7 @@ module Rgviz
315
319
  end
316
320
  false
317
321
  end
318
-
322
+
319
323
  def visit_format(node)
320
324
  node.column.accept self
321
325
  @s << ' '
@@ -326,7 +330,7 @@ module Rgviz
326
330
  end
327
331
  false
328
332
  end
329
-
333
+
330
334
  def visit_logical_expression(node)
331
335
  @s += "("
332
336
  node.operands.each_with_index do |operand, i|
@@ -336,9 +340,9 @@ module Rgviz
336
340
  @s += ")"
337
341
  false
338
342
  end
339
-
343
+
340
344
  def visit_binary_expression(node)
341
- if node.operator == BinaryExpression::Eq
345
+ if node.operator == BinaryExpression::Eq
342
346
  source = has_magic_name?(node.right)
343
347
  if source
344
348
  @s << "';\n"
@@ -346,7 +350,7 @@ module Rgviz
346
350
  when :html
347
351
  @s << "var s = rgviz_get_value('#{source[:id]}');\n"
348
352
  append_selections node, source
349
-
353
+
350
354
  @uses_rgviz_get_value = true
351
355
  when :js
352
356
  @s << "var s = #{source[:id]}();\n"
@@ -367,7 +371,7 @@ module Rgviz
367
371
  node.right.accept self
368
372
  false
369
373
  end
370
-
374
+
371
375
  def visit_unary_expression(node)
372
376
  if node.operator == UnaryExpression::Not
373
377
  @s << "not "
@@ -388,7 +392,7 @@ module Rgviz
388
392
  append_before_source_type source[:type]
389
393
  @s << " + rgviz_get_value('#{source[:id]}') + "
390
394
  append_after_source_type source[:type]
391
-
395
+
392
396
  @uses_rgviz_get_value = true
393
397
  when :js
394
398
  append_before_source_type source[:type]
@@ -401,35 +405,35 @@ module Rgviz
401
405
  @params << source[:id].to_i unless @params.include?(source[:id])
402
406
  end
403
407
  end
404
-
408
+
405
409
  def visit_number_column(node)
406
410
  @s << node.value.to_s
407
411
  end
408
-
412
+
409
413
  def visit_string_column(node)
410
414
  value = node.value.gsub('"', '\"')
411
415
  @s << "\"#{value}\""
412
416
  end
413
-
417
+
414
418
  def visit_boolean_column(node)
415
419
  @s << node.value.to_s
416
420
  end
417
-
421
+
418
422
  def visit_date_column(node)
419
423
  @s << "date \"#{node.value.to_s}\""
420
424
  end
421
-
425
+
422
426
  def visit_date_time_column(node)
423
427
  @s << "date \"#{node.value.strftime('%Y-%m-%d %H:%M:%S')}\""
424
428
  end
425
-
429
+
426
430
  def visit_time_of_day_column(node)
427
431
  @s << "date \"#{node.value.strftime('%H:%M:%S')}\""
428
432
  end
429
-
433
+
430
434
  def visit_scalar_function_column(node)
431
435
  case node.function
432
- when ScalarFunctionColumn::Sum, ScalarFunctionColumn::Difference,
436
+ when ScalarFunctionColumn::Sum, ScalarFunctionColumn::Difference,
433
437
  ScalarFunctionColumn::Product, ScalarFunctionColumn::Quotient
434
438
  node.arguments[0].accept node
435
439
  @s << " #{node.function} "
@@ -444,21 +448,21 @@ module Rgviz
444
448
  end
445
449
  false
446
450
  end
447
-
451
+
448
452
  def visit_aggregate_column(node)
449
453
  @s << "#{node.function}("
450
454
  node.argument.accept self
451
455
  @s << ")"
452
456
  false
453
457
  end
454
-
458
+
455
459
  def print_columns(node)
456
460
  node.columns.each_with_index do |c, i|
457
461
  @s << ', ' if i > 0
458
462
  c.accept self
459
463
  end
460
464
  end
461
-
465
+
462
466
  def get_source(name, include_type = true)
463
467
  if name.start_with?(@html_prefix)
464
468
  if include_type
@@ -482,7 +486,7 @@ module Rgviz
482
486
  {}
483
487
  end
484
488
  end
485
-
489
+
486
490
  def get_source_type(source, name)
487
491
  if name.start_with?('number_')
488
492
  {:source => source, :id => name[7 .. -1], :type => :number}
@@ -498,7 +502,7 @@ module Rgviz
498
502
  {:source => source, :id => name, :type => :string}
499
503
  end
500
504
  end
501
-
505
+
502
506
  def append_before_source_type(type)
503
507
  case type
504
508
  when :number
@@ -513,7 +517,7 @@ module Rgviz
513
517
  @s << "timeofday \"'"
514
518
  end
515
519
  end
516
-
520
+
517
521
  def append_after_source_type(type)
518
522
  case type
519
523
  when :number
@@ -522,7 +526,7 @@ module Rgviz
522
526
  @s << "'\""
523
527
  end
524
528
  end
525
-
529
+
526
530
  def append_selections(node, source)
527
531
  @s << "q += rgviz_append(s, '";
528
532
  node.left.accept self
@@ -533,7 +537,7 @@ module Rgviz
533
537
  @s << "');\n"
534
538
  @uses_rgviz_append = true
535
539
  end
536
-
540
+
537
541
  def has_magic_name?(node)
538
542
  return false unless node.kind_of?(IdColumn)
539
543
  source = get_source node.name
data/spec/blueprints.rb CHANGED
@@ -23,10 +23,3 @@ Person.blueprint do
23
23
  birthday { Sham::date }
24
24
  city
25
25
  end
26
-
27
- Pet.blueprint do
28
- name
29
- age { Sham::number }
30
- birthday { Sham::date }
31
- the_city { City.make }
32
- end
@@ -5,12 +5,11 @@ include Rgviz
5
5
 
6
6
  describe Executor do
7
7
  before :each do
8
- [Person, Pet, City, Country].each &:delete_all
8
+ [Person, City, Country].each &:delete_all
9
9
  end
10
10
 
11
11
  def exec(query, options = {})
12
- clazz = options[:class] || Person
13
- exec = Executor.new clazz, query
12
+ exec = Executor.new Person, query
14
13
  exec.execute options
15
14
  end
16
15
 
@@ -287,14 +286,6 @@ describe Executor do
287
286
 
288
287
  it_processes_single_select_column "1 options no_values", 'c0', :number, nil, "1"
289
288
 
290
- it_processes_single_select_column "1 where city is null", 'c0', :number, 1, "1" do
291
- Person.make :city => nil
292
- end
293
-
294
- it_processes_single_select_column "the_city_name where the_city_name = 'foo'", 'the_city_name', :string, 'foo', "the_city_name", :class => Pet do
295
- Pet.make :the_city => (City.make :name => 'foo')
296
- end
297
-
298
289
  it "processes pivot" do
299
290
  Person.make :name => 'Eng', :birthday => '2000-01-12', :age => 1000
300
291
  Person.make :name => 'Eng', :birthday => '2000-01-12', :age => 500
data/spec/spec_helper.rb CHANGED
@@ -32,19 +32,9 @@ ActiveRecord::Schema.define do
32
32
  t.datetime "updated_at"
33
33
  t.integer "city_id"
34
34
  end
35
-
36
- create_table "pets", :force => true do |t|
37
- t.string "name"
38
- t.integer "age"
39
- t.date "birthday"
40
- t.datetime "created_at"
41
- t.datetime "updated_at"
42
- t.integer "city_id"
43
- end
44
35
  end
45
36
 
46
37
  require File.dirname(__FILE__) + '/models/person'
47
- require File.dirname(__FILE__) + '/models/pet'
48
38
  require File.dirname(__FILE__) + '/models/city'
49
39
  require File.dirname(__FILE__) + '/models/country'
50
40
 
metadata CHANGED
@@ -1,12 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rgviz-rails
3
3
  version: !ruby/object:Gem::Version
4
- hash: 93
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
- - 43
9
- version: "0.43"
7
+ - 44
8
+ version: "0.44"
10
9
  platform: ruby
11
10
  authors:
12
11
  - Ary Borenszweig
@@ -14,10 +13,22 @@ autorequire:
14
13
  bindir: bin
15
14
  cert_chain: []
16
15
 
17
- date: 2010-09-14 00:00:00 -03:00
16
+ date: 2010-12-11 00:00:00 -03:00
18
17
  default_executable:
19
- dependencies: []
20
-
18
+ dependencies:
19
+ - !ruby/object:Gem::Dependency
20
+ name: rgviz
21
+ prerelease: false
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
21
32
  description:
22
33
  email: aborenszweig@manas.com.ar
23
34
  executables: []
@@ -25,7 +36,7 @@ executables: []
25
36
  extensions: []
26
37
 
27
38
  extra_rdoc_files:
28
- - README
39
+ - README.rdoc
29
40
  files:
30
41
  - lib/rgviz_rails.rb
31
42
  - lib/rgviz_rails/executor.rb
@@ -35,16 +46,15 @@ files:
35
46
  - lib/rgviz_rails/adapters/mysql_adapter.rb
36
47
  - lib/rgviz_rails/adapters/postgresql_adapter.rb
37
48
  - lib/rgviz_rails/adapters/sqlite_adapter.rb
38
- - rails/init.rb
49
+ - lib/rgviz_rails/init.rb
39
50
  - spec/blueprints.rb
40
51
  - spec/spec.opts
41
52
  - spec/spec_helper.rb
42
53
  - spec/models/city.rb
43
54
  - spec/models/country.rb
44
55
  - spec/models/person.rb
45
- - spec/models/pet.rb
46
56
  - spec/rgviz/executor_spec.rb
47
- - README
57
+ - README.rdoc
48
58
  has_rdoc: true
49
59
  homepage: http://code.google.com/p/rgviz-rails
50
60
  licenses: []
@@ -59,7 +69,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
59
69
  requirements:
60
70
  - - ">="
61
71
  - !ruby/object:Gem::Version
62
- hash: 3
63
72
  segments:
64
73
  - 0
65
74
  version: "0"
@@ -68,7 +77,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
77
  requirements:
69
78
  - - ">="
70
79
  - !ruby/object:Gem::Version
71
- hash: 3
72
80
  segments:
73
81
  - 0
74
82
  version: "0"
data/README DELETED
@@ -1,243 +0,0 @@
1
- == Welcome to Rails
2
-
3
- Rails is a web-application framework that includes everything needed to create
4
- database-backed web applications according to the Model-View-Control pattern.
5
-
6
- This pattern splits the view (also called the presentation) into "dumb" templates
7
- that are primarily responsible for inserting pre-built data in between HTML tags.
8
- The model contains the "smart" domain objects (such as Account, Product, Person,
9
- Post) that holds all the business logic and knows how to persist themselves to
10
- a database. The controller handles the incoming requests (such as Save New Account,
11
- Update Product, Show Post) by manipulating the model and directing data to the view.
12
-
13
- In Rails, the model is handled by what's called an object-relational mapping
14
- layer entitled Active Record. This layer allows you to present the data from
15
- database rows as objects and embellish these data objects with business logic
16
- methods. You can read more about Active Record in
17
- link:files/vendor/rails/activerecord/README.html.
18
-
19
- The controller and view are handled by the Action Pack, which handles both
20
- layers by its two parts: Action View and Action Controller. These two layers
21
- are bundled in a single package due to their heavy interdependence. This is
22
- unlike the relationship between the Active Record and Action Pack that is much
23
- more separate. Each of these packages can be used independently outside of
24
- Rails. You can read more about Action Pack in
25
- link:files/vendor/rails/actionpack/README.html.
26
-
27
-
28
- == Getting Started
29
-
30
- 1. At the command prompt, start a new Rails application using the <tt>rails</tt> command
31
- and your application name. Ex: rails myapp
32
- 2. Change directory into myapp and start the web server: <tt>script/server</tt> (run with --help for options)
33
- 3. Go to http://localhost:3000/ and get "Welcome aboard: You're riding the Rails!"
34
- 4. Follow the guidelines to start developing your application
35
-
36
-
37
- == Web Servers
38
-
39
- By default, Rails will try to use Mongrel if it's are installed when started with script/server, otherwise Rails will use WEBrick, the webserver that ships with Ruby. But you can also use Rails
40
- with a variety of other web servers.
41
-
42
- Mongrel is a Ruby-based webserver with a C component (which requires compilation) that is
43
- suitable for development and deployment of Rails applications. If you have Ruby Gems installed,
44
- getting up and running with mongrel is as easy as: <tt>gem install mongrel</tt>.
45
- More info at: http://mongrel.rubyforge.org
46
-
47
- Say other Ruby web servers like Thin and Ebb or regular web servers like Apache or LiteSpeed or
48
- Lighttpd or IIS. The Ruby web servers are run through Rack and the latter can either be setup to use
49
- FCGI or proxy to a pack of Mongrels/Thin/Ebb servers.
50
-
51
- == Apache .htaccess example for FCGI/CGI
52
-
53
- # General Apache options
54
- AddHandler fastcgi-script .fcgi
55
- AddHandler cgi-script .cgi
56
- Options +FollowSymLinks +ExecCGI
57
-
58
- # If you don't want Rails to look in certain directories,
59
- # use the following rewrite rules so that Apache won't rewrite certain requests
60
- #
61
- # Example:
62
- # RewriteCond %{REQUEST_URI} ^/notrails.*
63
- # RewriteRule .* - [L]
64
-
65
- # Redirect all requests not available on the filesystem to Rails
66
- # By default the cgi dispatcher is used which is very slow
67
- #
68
- # For better performance replace the dispatcher with the fastcgi one
69
- #
70
- # Example:
71
- # RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
72
- RewriteEngine On
73
-
74
- # If your Rails application is accessed via an Alias directive,
75
- # then you MUST also set the RewriteBase in this htaccess file.
76
- #
77
- # Example:
78
- # Alias /myrailsapp /path/to/myrailsapp/public
79
- # RewriteBase /myrailsapp
80
-
81
- RewriteRule ^$ index.html [QSA]
82
- RewriteRule ^([^.]+)$ $1.html [QSA]
83
- RewriteCond %{REQUEST_FILENAME} !-f
84
- RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
85
-
86
- # In case Rails experiences terminal errors
87
- # Instead of displaying this message you can supply a file here which will be rendered instead
88
- #
89
- # Example:
90
- # ErrorDocument 500 /500.html
91
-
92
- ErrorDocument 500 "<h2>Application error</h2>Rails application failed to start properly"
93
-
94
-
95
- == Debugging Rails
96
-
97
- Sometimes your application goes wrong. Fortunately there are a lot of tools that
98
- will help you debug it and get it back on the rails.
99
-
100
- First area to check is the application log files. Have "tail -f" commands running
101
- on the server.log and development.log. Rails will automatically display debugging
102
- and runtime information to these files. Debugging info will also be shown in the
103
- browser on requests from 127.0.0.1.
104
-
105
- You can also log your own messages directly into the log file from your code using
106
- the Ruby logger class from inside your controllers. Example:
107
-
108
- class WeblogController < ActionController::Base
109
- def destroy
110
- @weblog = Weblog.find(params[:id])
111
- @weblog.destroy
112
- logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
113
- end
114
- end
115
-
116
- The result will be a message in your log file along the lines of:
117
-
118
- Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1
119
-
120
- More information on how to use the logger is at http://www.ruby-doc.org/core/
121
-
122
- Also, Ruby documentation can be found at http://www.ruby-lang.org/ including:
123
-
124
- * The Learning Ruby (Pickaxe) Book: http://www.ruby-doc.org/docs/ProgrammingRuby/
125
- * Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
126
-
127
- These two online (and free) books will bring you up to speed on the Ruby language
128
- and also on programming in general.
129
-
130
-
131
- == Debugger
132
-
133
- Debugger support is available through the debugger command when you start your Mongrel or
134
- Webrick server with --debugger. This means that you can break out of execution at any point
135
- in the code, investigate and change the model, AND then resume execution!
136
- You need to install ruby-debug to run the server in debugging mode. With gems, use 'gem install ruby-debug'
137
- Example:
138
-
139
- class WeblogController < ActionController::Base
140
- def index
141
- @posts = Post.find(:all)
142
- debugger
143
- end
144
- end
145
-
146
- So the controller will accept the action, run the first line, then present you
147
- with a IRB prompt in the server window. Here you can do things like:
148
-
149
- >> @posts.inspect
150
- => "[#<Post:0x14a6be8 @attributes={\"title\"=>nil, \"body\"=>nil, \"id\"=>\"1\"}>,
151
- #<Post:0x14a6620 @attributes={\"title\"=>\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]"
152
- >> @posts.first.title = "hello from a debugger"
153
- => "hello from a debugger"
154
-
155
- ...and even better is that you can examine how your runtime objects actually work:
156
-
157
- >> f = @posts.first
158
- => #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
159
- >> f.
160
- Display all 152 possibilities? (y or n)
161
-
162
- Finally, when you're ready to resume execution, you enter "cont"
163
-
164
-
165
- == Console
166
-
167
- You can interact with the domain model by starting the console through <tt>script/console</tt>.
168
- Here you'll have all parts of the application configured, just like it is when the
169
- application is running. You can inspect domain models, change values, and save to the
170
- database. Starting the script without arguments will launch it in the development environment.
171
- Passing an argument will specify a different environment, like <tt>script/console production</tt>.
172
-
173
- To reload your controllers and models after launching the console run <tt>reload!</tt>
174
-
175
- == dbconsole
176
-
177
- You can go to the command line of your database directly through <tt>script/dbconsole</tt>.
178
- You would be connected to the database with the credentials defined in database.yml.
179
- Starting the script without arguments will connect you to the development database. Passing an
180
- argument will connect you to a different database, like <tt>script/dbconsole production</tt>.
181
- Currently works for mysql, postgresql and sqlite.
182
-
183
- == Description of Contents
184
-
185
- app
186
- Holds all the code that's specific to this particular application.
187
-
188
- app/controllers
189
- Holds controllers that should be named like weblogs_controller.rb for
190
- automated URL mapping. All controllers should descend from ApplicationController
191
- which itself descends from ActionController::Base.
192
-
193
- app/models
194
- Holds models that should be named like post.rb.
195
- Most models will descend from ActiveRecord::Base.
196
-
197
- app/views
198
- Holds the template files for the view that should be named like
199
- weblogs/index.html.erb for the WeblogsController#index action. All views use eRuby
200
- syntax.
201
-
202
- app/views/layouts
203
- Holds the template files for layouts to be used with views. This models the common
204
- header/footer method of wrapping views. In your views, define a layout using the
205
- <tt>layout :default</tt> and create a file named default.html.erb. Inside default.html.erb,
206
- call <% yield %> to render the view using this layout.
207
-
208
- app/helpers
209
- Holds view helpers that should be named like weblogs_helper.rb. These are generated
210
- for you automatically when using script/generate for controllers. Helpers can be used to
211
- wrap functionality for your views into methods.
212
-
213
- config
214
- Configuration files for the Rails environment, the routing map, the database, and other dependencies.
215
-
216
- db
217
- Contains the database schema in schema.rb. db/migrate contains all
218
- the sequence of Migrations for your schema.
219
-
220
- doc
221
- This directory is where your application documentation will be stored when generated
222
- using <tt>rake doc:app</tt>
223
-
224
- lib
225
- Application specific libraries. Basically, any kind of custom code that doesn't
226
- belong under controllers, models, or helpers. This directory is in the load path.
227
-
228
- public
229
- The directory available for the web server. Contains subdirectories for images, stylesheets,
230
- and javascripts. Also contains the dispatchers and the default HTML files. This should be
231
- set as the DOCUMENT_ROOT of your web server.
232
-
233
- script
234
- Helper scripts for automation and generation.
235
-
236
- test
237
- Unit and functional tests along with fixtures. When using the script/generate scripts, template
238
- test files will be generated for you and placed in this directory.
239
-
240
- vendor
241
- External libraries that the application depends on. Also includes the plugins subdirectory.
242
- If the app has frozen rails, those gems also go here, under vendor/rails/.
243
- This directory is in the load path.
data/spec/models/pet.rb DELETED
@@ -1,3 +0,0 @@
1
- class Pet < ActiveRecord::Base
2
- belongs_to :the_city, :class_name => 'City', :foreign_key => 'city_id'
3
- end