arspy 0.0.1
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/.gitignore +3 -0
- data/LICENSE +20 -0
- data/README.rdoc +0 -0
- data/Rakefile +101 -0
- data/init.rb +1 -0
- data/lib/arspy/class_extensions.rb +10 -0
- data/lib/arspy/delegators/active_record_extensions.rb +9 -0
- data/lib/arspy/delegators/array_extensions.rb +33 -0
- data/lib/arspy/delegators/association_collection_extensions.rb +34 -0
- data/lib/arspy/delegators/factory.rb +21 -0
- data/lib/arspy/delegators/null_extensions.rb +9 -0
- data/lib/arspy/delegators.rb +6 -0
- data/lib/arspy/operators.rb +129 -0
- data/lib/arspy.rb +26 -0
- data/lib/meta_programming/object.rb +33 -0
- data/lib/meta_programming.rb +7 -0
- data/spec/database.rb +63 -0
- metadata +78 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2006-2009 Jeff Patmon
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
#require 'rake/testtask'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'gem_versions'
|
5
|
+
#require 'rake/contrib/sshpublisher'
|
6
|
+
|
7
|
+
spec = Gem::Specification.new do |s|
|
8
|
+
s.name = 'arspy'
|
9
|
+
s.version = GemVersions.get_version
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.description = 'Active Record Spy'
|
12
|
+
s.summary = 'Rails console command line tool for browsing and inspecting the structure, associations and data of an ActiveRecord data model.'
|
13
|
+
|
14
|
+
exclude_folders = '' # 'spec/rails/{doc,lib,log,nbproject,tmp,vendor,test}'
|
15
|
+
exclude_files = [] # FileList['**/*.log'] + FileList[exclude_folders+'/**/*'] + FileList[exclude_folders]
|
16
|
+
s.files = FileList['{lib,spec}/**/*'] + %w(init.rb LICENSE Rakefile README.rdoc .gitignore) - exclude_files
|
17
|
+
s.require_path = 'lib'
|
18
|
+
s.has_rdoc = true
|
19
|
+
s.test_files = Dir['spec/*_spec.rb']
|
20
|
+
|
21
|
+
s.author = 'Jeff Patmon'
|
22
|
+
s.email = 'jpatmon@gmail.com'
|
23
|
+
s.homepage = 'http://github.com/jeffp/arspy/tree/master'
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'spec/version'
|
27
|
+
require 'spec/rake/spectask'
|
28
|
+
|
29
|
+
desc "Run specs"
|
30
|
+
namespace :spec do
|
31
|
+
task :default=>:object
|
32
|
+
Spec::Rake::SpecTask.new(:object) do |t|
|
33
|
+
t.spec_files = FileList['spec/*_spec.rb']
|
34
|
+
t.libs << 'lib' << 'spec'
|
35
|
+
t.rcov = false
|
36
|
+
t.spec_opts = ['--options', 'spec/spec.opts']
|
37
|
+
#t.rcov_dir = 'coverage'
|
38
|
+
#t.rcov_opts = ['--exclude', "kernel,load-diff-lcs\.rb,instance_exec\.rb,lib/spec.rb,lib/spec/runner.rb,^spec/*,bin/spec,examples,/gems,/Library/Ruby,\.autotest,#{ENV['GEM_HOME']}"]
|
39
|
+
end
|
40
|
+
=begin
|
41
|
+
Spec::Rake::SpecTask.new(:sub) do |t|
|
42
|
+
t.spec_files = FileList['spec/inheritance_spec.rb']
|
43
|
+
t.libs << 'lib' << 'spec'
|
44
|
+
t.rcov = false
|
45
|
+
t.spec_opts = ['--options', 'spec/spec.opts']
|
46
|
+
end
|
47
|
+
Spec::Rake::SpecTask.new(:poro) do |t|
|
48
|
+
t.spec_files = FileList['spec/poro_spec.rb']
|
49
|
+
t.libs << 'lib' << 'spec'
|
50
|
+
t.rcov = false
|
51
|
+
t.spec_opts = ['--options', 'spec/spec.opts']
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "Run ActiveRecord integration specs"
|
55
|
+
Spec::Rake::SpecTask.new(:active_record) do |t|
|
56
|
+
t.spec_files = FileList['spec/active_record/*_spec.rb']
|
57
|
+
t.libs << 'lib' << 'spec/active_record'
|
58
|
+
t.spec_opts = ['--options', 'spec/spec.opts']
|
59
|
+
t.rcov = false
|
60
|
+
end
|
61
|
+
Spec::Rake::SpecTask.new(:forms) do |t|
|
62
|
+
t.spec_files = FileList['spec/rails/spec/integrations/*_spec.rb']
|
63
|
+
t.libs << 'lib' << 'spec/rails/spec'
|
64
|
+
t.spec_opts = ['--options', 'spec/spec.opts']
|
65
|
+
t.rcov = false
|
66
|
+
end
|
67
|
+
# Spec::Rake::SpecTask.new(:associations) do |t|
|
68
|
+
# t.spec_files = FileList['spec/active_record/associations_spec.rb']
|
69
|
+
# t.libs << 'lib' << 'spec/active_record'
|
70
|
+
# t.rcov = false
|
71
|
+
# end
|
72
|
+
desc "Run all specs"
|
73
|
+
task :all=>[:object, :active_record, :forms]
|
74
|
+
=end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
desc "Generate documentation for the #{spec.name} gem."
|
79
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
80
|
+
rdoc.rdoc_dir = 'rdoc'
|
81
|
+
rdoc.title = spec.name
|
82
|
+
#rdoc.template = '../rdoc_template.rb'
|
83
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
84
|
+
rdoc.rdoc_files.include('README.rdoc', 'LICENSE', 'lib/**/*.rb')
|
85
|
+
end
|
86
|
+
|
87
|
+
desc 'Generate a gemspec file.'
|
88
|
+
task :gemspec do
|
89
|
+
File.open("#{spec.name}.gemspec", 'w') do |f|
|
90
|
+
f.write spec.to_ruby
|
91
|
+
end
|
92
|
+
GemVersions.increment_version
|
93
|
+
end
|
94
|
+
|
95
|
+
Rake::GemPackageTask.new(spec) do |p|
|
96
|
+
p.gem_spec = spec
|
97
|
+
p.need_tar = RUBY_PLATFORM =~ /mswin/ ? false : true
|
98
|
+
p.need_zip = true
|
99
|
+
end
|
100
|
+
|
101
|
+
Dir['tasks/**/*.rake'].each {|rake| load rake}
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'arspy'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Arspy
|
2
|
+
module Delegators
|
3
|
+
module ArrayExtensions
|
4
|
+
def self.included(base)
|
5
|
+
base.define_chained_method(:method_missing, :arspy) do |symbol, *args|
|
6
|
+
result = Arspy::Operators.interpret(self, symbol, *args)
|
7
|
+
result = method_missing_without_arspy(symbol, *args) unless result
|
8
|
+
result
|
9
|
+
end
|
10
|
+
base.define_chained_method(:id, :arspy) do
|
11
|
+
return id_without_arspy if (self.empty? || !self.first.is_a?(ActiveRecord::Base))
|
12
|
+
self.map(&:id)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def la
|
17
|
+
Arspy::Operators.la(self.first.class) unless (self.emtpy? || !(self.first.is_a?(ActiveRecord::Base)))
|
18
|
+
end
|
19
|
+
def lf
|
20
|
+
Arspy::Operators.lf(self.first.class) unless (self.empty? || !(self.first.is_a?(ActiveRecord::Base)))
|
21
|
+
end
|
22
|
+
def pr(*args)
|
23
|
+
Arspy::Operators.print_array(self, *args)
|
24
|
+
end
|
25
|
+
def wi(*args)
|
26
|
+
Arspy::Operators.with(self, *args)
|
27
|
+
end
|
28
|
+
def wo(*args)
|
29
|
+
Arspy::Operators.without(self, *args)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Arspy
|
2
|
+
module Delegators
|
3
|
+
module AssociationCollectionExtensions
|
4
|
+
def self.included(base)
|
5
|
+
base.define_chained_method(:method_missing, :arspy) do |symbol, *args|
|
6
|
+
load_target unless loaded?
|
7
|
+
result = Arspy::Operators.interpret(@target, symbol, *args)
|
8
|
+
result = method_missing_without_arspy(symbol, *args) unless result
|
9
|
+
result
|
10
|
+
end
|
11
|
+
end
|
12
|
+
def pr(*args)
|
13
|
+
load_target unless loaded?
|
14
|
+
Arspy::Operators.print_array(@target, *args)
|
15
|
+
end
|
16
|
+
def la
|
17
|
+
load_target unless loaded?
|
18
|
+
Arspy::Operators.la(@target.first.class) unless (@target.emtpy? || !(@target.first.is_a?(ActiveRecord::Base)))
|
19
|
+
end
|
20
|
+
def lf
|
21
|
+
load_target unless loaded?
|
22
|
+
Arspy::Operators.lf(@target.first.class) unless (@target.empty? || !(@target.first.is_a?(ActiveRecord::Base)))
|
23
|
+
end
|
24
|
+
def wi(*args)
|
25
|
+
load_target unless loaded?
|
26
|
+
Arspy::Operators.with(@target, *args)
|
27
|
+
end
|
28
|
+
def wo(*args)
|
29
|
+
load_target unless loaded?
|
30
|
+
Arspy::Operators.without(@target, *args)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'arspy/delegators/null_extensions'
|
2
|
+
require 'arspy/delegators/array_extensions'
|
3
|
+
require 'arspy/delegators/association_collection_extensions'
|
4
|
+
require 'arspy/delegators/active_record_extensions'
|
5
|
+
|
6
|
+
module Arspy
|
7
|
+
module Delegators
|
8
|
+
module Factory
|
9
|
+
def self.module_for(klass)
|
10
|
+
case klass.name
|
11
|
+
when 'Array' then Arspy::Delegators::ArrayExtensions
|
12
|
+
when 'ActiveRecord::Base' then Arspy::Delegators::ActiveRecordExtensions
|
13
|
+
when 'ActiveRecord::Associations::HasManyThroughAssociation', 'ActiveRecord::Associations::AssociationCollection'
|
14
|
+
then Arspy::Delegators::AssociationCollectionExtensions
|
15
|
+
else
|
16
|
+
Arspy::Delegators::NullExtensions
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module Arspy
|
2
|
+
module Operators
|
3
|
+
def self.la(active_record_klass)
|
4
|
+
counts = {}
|
5
|
+
rows = active_record_klass.reflect_on_all_associations.map do |a|
|
6
|
+
counts[a.macro] ||= 0
|
7
|
+
counts[a.macro] += 1
|
8
|
+
self.format_column_association(a)
|
9
|
+
end
|
10
|
+
rows.sort!{|a,b| a.first <=> b.first}
|
11
|
+
self.print_matrix(rows)
|
12
|
+
"Total: #{counts.inject(0){|sum, c| sum+c.last}} (" + counts.map{|c| "#{c.last} #{c.first}" }.join(', ') + ")"
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.lf(active_record_klass)
|
16
|
+
rows = active_record_klass.columns.map do |c|
|
17
|
+
self.format_column_field(c)
|
18
|
+
end
|
19
|
+
rows.sort!{|a,b| a.first <=> b.first}
|
20
|
+
self.print_matrix(rows)
|
21
|
+
"Total #{active_record_klass.columns.size} field#{active_record_klass.columns.size == 1 ? '' : 's'}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.format_column_association(a)
|
25
|
+
select_options = a.options.select{|k,v| [:through, :as, :polymorphic].include?(k)}
|
26
|
+
[a.name.to_s, a.macro.to_s, "(#{a.options[:class_name] || a.name.to_s.singularize.camelize})", select_options.empty? ? '' : Hash[*select_options.flatten].inspect]
|
27
|
+
end
|
28
|
+
def self.format_column_field(f)
|
29
|
+
[f.name.to_s, ":#{f.type}", "(#{f.sql_type})"]
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.print_array(array, *args)
|
33
|
+
array.each{|element| puts element.is_a?(String) ? element : element.inspect } if args.empty?
|
34
|
+
self.print_matrix(
|
35
|
+
array.map do |obj|
|
36
|
+
args.map do |arg|
|
37
|
+
case arg
|
38
|
+
when Symbol then obj.__send__(arg)
|
39
|
+
when String then obj.respond_to?(arg) ? obj.__send__(arg) : (obj.instance_eval(arg) rescue nil)
|
40
|
+
else nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
) unless args.empty?
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.print_object(object, *args)
|
49
|
+
print_matrix([args.map{|a| object[a]}]) if args
|
50
|
+
puts(object.inspect) unless args
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
def self.test_object(obj, args)
|
54
|
+
args.any? do |arg|
|
55
|
+
case arg
|
56
|
+
when String then obj.instance_eval(arg) rescue false
|
57
|
+
when Integer then obj.id == arg
|
58
|
+
when Hash
|
59
|
+
arg.any?{|k,v| self.test_attribute(obj, k, (v.is_a?(Array) ? v : [v]) ) }
|
60
|
+
else
|
61
|
+
false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
def self.with(array, *args)
|
66
|
+
return array if (args.empty? || array.nil? || array.empty?)
|
67
|
+
array.select{|o| o && self.test_object(o, args)}
|
68
|
+
end
|
69
|
+
def self.without(array, *args)
|
70
|
+
return array if (args.empty? || array.nil? || array.empty?)
|
71
|
+
array.select{|o| o && !self.test_object(o, args)}
|
72
|
+
end
|
73
|
+
def self.interpret(array, symbol, *args)
|
74
|
+
return nil unless (array && symbol)
|
75
|
+
return nil unless (array.is_a?(Array) && !array.empty? && array.first.is_a?(ActiveRecord::Base))
|
76
|
+
|
77
|
+
if array.first.class.reflect_on_all_associations.detect{|a| a.name == symbol}
|
78
|
+
array.map(&symbol).flatten
|
79
|
+
elsif (array.first.attribute_names.include?(symbol.to_s) || array.first.respond_to?(symbol))
|
80
|
+
return array.map(&symbol) if args.empty?
|
81
|
+
raise 'Hash not allowed as attribute conditionals' if args.any?{|a| a.is_a?(Hash)}
|
82
|
+
array.select{|o| o && self.test_attribute(o, symbol, args)}
|
83
|
+
else
|
84
|
+
nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.test_attribute(obj, attr_sym, args)
|
89
|
+
return false if (obj.nil? || attr_sym.nil? || args.empty?)
|
90
|
+
value = obj.__send__(attr_sym)
|
91
|
+
args.any? do |arg|
|
92
|
+
case arg
|
93
|
+
when String then (arg == value || (obj.instance_eval("#{attr_sym} #{arg}") rescue false))
|
94
|
+
when Regexp then arg.match(value)
|
95
|
+
when Range then arg.include?(value)
|
96
|
+
when Integer then (value.is_a?(ActiveRecord::Base) ? arg == value.id : arg == value) #TODO: what about value is association collection
|
97
|
+
when Float then arg == value
|
98
|
+
else
|
99
|
+
false
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.prepare_arguments(symbol, *args)
|
105
|
+
return nil if args.empty?
|
106
|
+
Hash[*args.map{|a| a.is_a?(Hash) ? a.map{|k,v| [k, v]} : [symbol, a]}.flatten]
|
107
|
+
end
|
108
|
+
|
109
|
+
@@column_padding = 2
|
110
|
+
def self.print_matrix(matrix_array)
|
111
|
+
return nil if matrix_array.empty?
|
112
|
+
raise 'Cannot print a non-matrix array' unless matrix_array.all?{|ar| ar.is_a? Array }
|
113
|
+
|
114
|
+
columns_per_row = matrix_array.map{|ar| ar.size }.max
|
115
|
+
init_array = Array.new(columns_per_row, 0)
|
116
|
+
max_widths = matrix_array.inject(init_array)do |mw, row|
|
117
|
+
row.each_with_index do |string, index|
|
118
|
+
mw[index] = [string.to_s.length, mw[index]].max
|
119
|
+
end
|
120
|
+
mw
|
121
|
+
end
|
122
|
+
matrix_array.each do |row|
|
123
|
+
index = -1
|
124
|
+
puts (row.map{|column| column.to_s + ' '*(max_widths[index += 1] - column.to_s.length) }.join(' '*@@column_padding))
|
125
|
+
end
|
126
|
+
nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
data/lib/arspy.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
raise 'Arspy only runs in an ActiveRecord environment' unless defined?(ActiveRecord::Base)
|
2
|
+
$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
require 'active_support/core_ext/string/inflections'
|
5
|
+
require 'meta_programming'
|
6
|
+
require 'arspy/operators'
|
7
|
+
require 'arspy/delegators'
|
8
|
+
require 'arspy/class_extensions'
|
9
|
+
|
10
|
+
module Arspy
|
11
|
+
def self.included(base)
|
12
|
+
base.send :include, Delegators::Factory.module_for(base)
|
13
|
+
extension = "Arspy::ClassExtensions::#{base.name}".constantize rescue nil
|
14
|
+
base.extend(extension) if extension
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
a = ActiveRecord::Associations
|
19
|
+
returning([Array, ActiveRecord::Base, a::AssociationCollection ]) { |classes|
|
20
|
+
unless a::HasManyThroughAssociation.superclass == a::HasManyAssociation
|
21
|
+
classes << a::HasManyThroughAssociation
|
22
|
+
end
|
23
|
+
}.each do |klass|
|
24
|
+
klass.send :include, Arspy
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module MetaProgramming
|
2
|
+
module Object
|
3
|
+
def self.included(base)
|
4
|
+
raise 'This module may only be included in class Object' unless base.name == 'Object'
|
5
|
+
base.extend(ClassExtensions)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassExtensions
|
9
|
+
def metaclass
|
10
|
+
class << self; self; end
|
11
|
+
end
|
12
|
+
def safe_alias_method_chain(method_name, ext)
|
13
|
+
class_eval do
|
14
|
+
method_name_with_ext = "#{method_name}_with_#{ext}".to_sym
|
15
|
+
if (method_defined?(method_name_with_ext) && !(metaclass.instance_variable_defined?("@#{method_name_with_ext}")))
|
16
|
+
if method_defined?(method_name.to_sym)
|
17
|
+
alias_method_chain(method_name.to_sym, ext.to_sym)
|
18
|
+
else
|
19
|
+
alias_method method_name.to_sym, method_name_with_ext
|
20
|
+
define_method("#{method_name}_without_#{ext}".to_sym) {|*args| }
|
21
|
+
end
|
22
|
+
metaclass.instance_variable_set("@#{method_name_with_ext}", true)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def define_chained_method(method_name, ext, &block)
|
28
|
+
define_method("#{method_name}_with_#{ext}".to_sym, block)
|
29
|
+
safe_alias_method_chain(method_name.to_sym, ext)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/spec/database.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
gem 'activerecord', ENV['AR_VERSION'] ? "=#{ENV['AR_VERSION']}" : '>=2.1.0'
|
4
|
+
require 'active_record'
|
5
|
+
|
6
|
+
ActiveRecord::Base.establish_connection({'adapter' => 'sqlite3', 'database' => ':memory:'})
|
7
|
+
ActiveRecord::Base.logger = Logger.new("#{File.dirname(__FILE__)}/active_record.log")
|
8
|
+
cx = ActiveRecord::Base.connection
|
9
|
+
|
10
|
+
cx.create_table(:things, :force=>true) do |t|
|
11
|
+
|
12
|
+
end
|
13
|
+
cx.create_table(:one_manies, :force=>true) do |t|
|
14
|
+
|
15
|
+
end
|
16
|
+
cx.create_table(:many_manies, :force=>true) do |t|
|
17
|
+
|
18
|
+
end
|
19
|
+
cx.create_table(:many_manies_things, :force=>true) do |t|
|
20
|
+
|
21
|
+
end
|
22
|
+
cx.create_table(:manies_one, :force=>true) do |t|
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
#basic_associations
|
27
|
+
connection.create_table(:companies, :force=>true) do |t|
|
28
|
+
t.string :name
|
29
|
+
t.string :status
|
30
|
+
end
|
31
|
+
connection.create_table(:contract_workers, :force=>true) do |t|
|
32
|
+
t.references :company
|
33
|
+
t.references :contractor
|
34
|
+
t.string :status
|
35
|
+
end
|
36
|
+
connection.create_table(:licenses, :force=>true) do |t|
|
37
|
+
t.references :company
|
38
|
+
t.string :status
|
39
|
+
end
|
40
|
+
connection.create_table(:contractors, :force=>true) do |t|
|
41
|
+
t.string :name
|
42
|
+
t.string :status
|
43
|
+
end
|
44
|
+
connection.create_table(:employees, :force=>true) do |t|
|
45
|
+
t.references :company
|
46
|
+
t.string :name
|
47
|
+
t.string :status
|
48
|
+
end
|
49
|
+
|
50
|
+
#polymorphic_associations
|
51
|
+
connection.create_table(:comments, :force=>true) do |t|
|
52
|
+
t.references :document, :polymorphic=>true
|
53
|
+
t.text :comment
|
54
|
+
t.string :status
|
55
|
+
end
|
56
|
+
connection.create_table(:articles, :force=>true) do |t|
|
57
|
+
t.string :name
|
58
|
+
t.string :status
|
59
|
+
end
|
60
|
+
connection.create_table(:images, :force=>true) do |t|
|
61
|
+
t.string :name
|
62
|
+
t.string :status
|
63
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: arspy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Jeff Patmon
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-04-03 00:00:00 -07:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Active Record Spy
|
22
|
+
email: jpatmon@gmail.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- lib/meta_programming/object.rb
|
31
|
+
- lib/arspy/class_extensions.rb
|
32
|
+
- lib/arspy/delegators/factory.rb
|
33
|
+
- lib/arspy/delegators/association_collection_extensions.rb
|
34
|
+
- lib/arspy/delegators/array_extensions.rb
|
35
|
+
- lib/arspy/delegators/null_extensions.rb
|
36
|
+
- lib/arspy/delegators/active_record_extensions.rb
|
37
|
+
- lib/arspy/delegators.rb
|
38
|
+
- lib/arspy/operators.rb
|
39
|
+
- lib/meta_programming.rb
|
40
|
+
- lib/arspy.rb
|
41
|
+
- spec/database.rb
|
42
|
+
- init.rb
|
43
|
+
- LICENSE
|
44
|
+
- Rakefile
|
45
|
+
- README.rdoc
|
46
|
+
- .gitignore
|
47
|
+
has_rdoc: true
|
48
|
+
homepage: http://github.com/jeffp/arspy/tree/master
|
49
|
+
licenses: []
|
50
|
+
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options: []
|
53
|
+
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
version: "0"
|
70
|
+
requirements: []
|
71
|
+
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.3.6
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: Rails console command line tool for browsing and inspecting the structure, associations and data of an ActiveRecord data model.
|
77
|
+
test_files: []
|
78
|
+
|