rgviz-rails 0.43 → 0.44

Sign up to get free protection for your applications and to get access to all the features.
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