garden 0.0.4.pre → 0.0.5.pre

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.
@@ -0,0 +1,30 @@
1
+ module Garden
2
+ module Helpers
3
+ module RealInstance
4
+ def get_real_instance(table, id)
5
+ model_name = table.is_a?(ActiveRecord::Reflection::AssociationReflection) ? table.class_name : table.to_s.classify
6
+
7
+ begin
8
+ clazz = model_name.constantize
9
+ raise "Class #{clazz.to_s} is not an ActiveRecord subclass." unless clazz.new.is_a?(ActiveRecord::Base)
10
+ instance = clazz.find(id.to_s)
11
+
12
+ # puts "!! Created clazz #{clazz.to_s} from model_name. No problem. #{instance.class.to_s} #{instance.to_param}"
13
+
14
+ return instance
15
+ rescue ActiveRecord::RecordNotFound => e
16
+
17
+ instance = clazz.find_by_name(id.to_s) if instance.nil? && clazz.respond_to?(:find_by_name)
18
+ # puts "++Find #{clazz.to_s} by title: #{id}" if instance.nil? && clazz.respond_to?(:find_by_title)
19
+ instance = clazz.find_by_title(id.to_s) if instance.nil? && clazz.respond_to?(:find_by_title)
20
+ # puts "++#{instance}" if instance
21
+ return instance
22
+ rescue Exception => e
23
+ puts "Could not find #{id} from table #{model_name}: #{e.message}"
24
+ return nil
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,7 @@
1
+ module Garden
2
+ # @private
3
+ module Helpers
4
+ autoload :RealInstance, 'garden/helpers/real_instance'
5
+ end
6
+
7
+ end
@@ -0,0 +1,157 @@
1
+
2
+ module Garden
3
+ class Instance
4
+
5
+ module Reflection
6
+ # If an association method is passed in (f.input :author) try to find the
7
+ # reflection object.
8
+ def reflection_for(method) #:nodoc:
9
+ if @object.class.respond_to?(:reflect_on_association)
10
+ @object.class.reflect_on_association(method)
11
+ elsif @object.class.respond_to?(:associations) # MongoMapper uses the 'associations(method)' instead
12
+ @object.class.associations(method)
13
+ end
14
+ end
15
+
16
+ def association_macro_for_method(method) #:nodoc:
17
+ reflection = reflection_for(method)
18
+ reflection.macro if reflection
19
+ end
20
+
21
+ def association_primary_key_for_method(method) #:nodoc:
22
+ reflection = reflection_for(method)
23
+ if reflection
24
+ case association_macro_for_method(method)
25
+ when :has_and_belongs_to_many, :has_many, :references_and_referenced_in_many, :references_many
26
+ :"#{method.to_s.singularize}_ids"
27
+ else
28
+ return reflection.foreign_key.to_sym if reflection.respond_to?(:foreign_key)
29
+ return reflection.options[:foreign_key].to_sym unless reflection.options[:foreign_key].blank?
30
+ :"#{method}_id"
31
+ end
32
+ else
33
+ method.to_sym
34
+ end
35
+ end
36
+ end
37
+ module Columns
38
+ # Get a column object for a specified attribute method - if possible.
39
+ def column_for(method) #:nodoc:
40
+ @object.column_for_attribute(method) if @object.respond_to?(:column_for_attribute)
41
+ end
42
+ end
43
+
44
+ include Reflection
45
+ include Columns
46
+
47
+ def initialize(clazz, attributes=nil)
48
+ @object = clazz.new
49
+ assign_attributes attributes if attributes
50
+ end
51
+
52
+ def assign_attributes(attributes)
53
+
54
+ attributes.each do |key, value|
55
+ map_attribute key, value
56
+ end
57
+
58
+
59
+
60
+ # parse_row_relationships @object, attributes#, relationships
61
+
62
+ # puts "A: #{attributes.keys}"
63
+
64
+ # rejected = {}
65
+ # attributes.each_key do |key|
66
+ # rejected[key] = attributes.delete(key) if !@object.attributes.include?(key.to_s)# && !relationships.include?(key.to_s)
67
+ # end
68
+
69
+
70
+ # attributes.delete_if do |key, value| !@object.attributes.include?(key.to_s) end
71
+
72
+ # see https://github.com/justinfrench/formtastic/blob/master/lib/formtastic/helpers/input_helper.rb
73
+
74
+ # @object.attributes = attributes
75
+
76
+ # @object.id = rejected[:id] if rejected.key?(:id)
77
+
78
+
79
+ if @object.valid?
80
+ @object.save!
81
+ puts ".Saved instance: #{@clazz} #{@object.to_param}"
82
+ else
83
+ puts "Invalid instance."
84
+ puts "#{@name}:"
85
+ # puts " - Valid attributes: #{attributes.keys}"
86
+ # puts " - Excel sheet keys: #{all_keys}"
87
+ # puts " - Invalid attributes: #{rejected.keys}"
88
+ # puts " - Association attributes: #{relationships}"
89
+ puts "Attributes from excel: #{attributes}"
90
+ # @object.errors.each do |error|
91
+ # puts "Error => #{error}: #{@object.errors.get error}"
92
+ # end
93
+ puts @object.errors.to_a
94
+ puts "."
95
+ end
96
+ end
97
+
98
+ def map_attribute(key, value)
99
+
100
+ if reflection = reflection_for(key)
101
+ # There is an assocation for this column.
102
+ case reflection.macro
103
+ when :has_many
104
+ parse_has_many(reflection, value)
105
+ when :belongs_to
106
+ parse_belongs_to(reflection, value)
107
+ end
108
+
109
+ return
110
+
111
+ end
112
+
113
+ if column = column_for(key)
114
+
115
+ case column.type
116
+
117
+ # Special cases where the column type doesn't map to an input method.
118
+ when :string
119
+
120
+ when :integer
121
+
122
+ when :float, :decimal
123
+
124
+ when :timestamp
125
+ # todo: parse a timestamp
126
+ when :boolean
127
+ value = ((value =~ /y|yes|true|t|1/i) || -1) >= 0
128
+ end
129
+
130
+ @object.send "#{key}=", value
131
+ end
132
+
133
+ end
134
+
135
+ def parse_has_many r, value
136
+ # puts " // Parsing #{r.name}, #{value}"
137
+ ids = value.split(/\s*,\s*/)
138
+ ids.each do |id|
139
+ related_instance = get_real_instance r.class_name, id
140
+ # puts ">> Creating a has-many relationship. #{id}, #{related_instance}"
141
+ unless related_instance.nil?
142
+ @object.send(r.name.to_sym) << related_instance
143
+ end
144
+ end
145
+ end
146
+
147
+ def parse_belongs_to r, value
148
+ ri = get_real_instance(r, value)
149
+ @object.attributes = { r.name.to_sym => ri }
150
+ # puts "Parsing Belongs_To. #{@object.class} #{@object.to_param} --- #{r.name.to_sym} --- #{ri.class} #{ri.to_param}"
151
+ end
152
+
153
+ end
154
+
155
+ Instance.send :include, Helpers::RealInstance
156
+
157
+ end
@@ -5,33 +5,6 @@ module Garden
5
5
  def self.parse_table_name namish
6
6
  namish.parameterize.underscore
7
7
  end
8
- def self.get_instance table, id
9
-
10
- model_name = table.is_a?(ActiveRecord::Reflection::AssociationReflection) ? table.class_name : table.to_s.classify
11
-
12
- # puts "Find #{id} from #{table_name}"
13
- # puts id.class.to_s
14
-
15
- begin
16
- clazz = model_name.constantize
17
- raise "Class #{clazz.to_s} is not an ActiveRecord subclass." unless clazz.new.is_a?(ActiveRecord::Base)
18
- instance = clazz.find(id.to_s)
19
-
20
- # puts "!! Created clazz #{clazz.to_s} from model_name. No problem. #{instance.class.to_s} #{instance.to_param}"
21
-
22
- return instance
23
- rescue ActiveRecord::RecordNotFound => e
24
-
25
- instance = clazz.find_by_name(id.to_s) if instance.nil? && clazz.respond_to?(:find_by_name)
26
- # puts "++Find #{clazz.to_s} by title: #{id}" if instance.nil? && clazz.respond_to?(:find_by_title)
27
- instance = clazz.find_by_title(id.to_s) if instance.nil? && clazz.respond_to?(:find_by_title)
28
- # puts "++#{instance}" if instance
29
- return instance
30
- rescue Exception => e
31
- puts "Could not find #{id} from table #{model_name}: #{e.message}"
32
- return nil
33
- end
34
- end
35
8
 
36
9
  def initialize namish
37
10
 
@@ -67,88 +40,9 @@ module Garden
67
40
  # end
68
41
  #
69
42
  def create_instance attributes
70
- # relationships = @relationships
71
-
72
- all_keys = attributes.keys
73
-
74
- instance = @clazz.new
75
- parse_row_relationships instance, attributes#, relationships
76
-
77
- # puts "A: #{attributes.keys}"
78
-
79
- # rejected = {}
80
- # attributes.each_key do |key|
81
- # rejected[key] = attributes.delete(key) if !instance.attributes.include?(key.to_s)# && !relationships.include?(key.to_s)
82
- # end
83
-
84
-
85
- attributes.delete_if do |key, value| !instance.attributes.include?(key.to_s) end
86
- instance.attributes = attributes
87
-
88
- # instance.id = rejected[:id] if rejected.key?(:id)
89
-
90
- # puts "Valid? #{instance.valid?}"
91
- # puts instance.errors.to_s
92
-
93
- valid = instance.valid?
94
-
95
- if instance.valid?
96
- instance.save!
97
- puts ".Saved instance: #{@clazz} #{instance.to_param}"
98
- else
99
- puts "Invalid instance."
100
- puts "#{@name}:"
101
- puts " - Valid attributes: #{attributes.keys}"
102
- puts " - Excel sheet keys: #{all_keys}"
103
- # puts " - Invalid attributes: #{rejected.keys}"
104
- # puts " - Association attributes: #{relationships}"
105
- instance.errors.each do |error|
106
- puts error
107
- end
108
- end
43
+ Instance.new @clazz, attributes
109
44
  end
110
-
111
- def parse_row_relationships instance, hash#, relationships
112
- @clazz.reflections.each_value do |r|
113
- next unless hash.has_key?(r.name)
114
- # Remove the value from the hash.
115
- value = hash.delete(r.name.to_sym)
116
- case r.macro
117
- when :has_many
118
- parse_has_many(instance, r, value)
119
- when :belongs_to
120
- parse_belongs_to(instance, r, value)
121
- end
122
- end
123
-
124
- # relationships.each do |r|
125
- # # puts "Parsing row relationship: #{hash[r.to_sym]}"
126
- # instance = get_instance r, hash[r.to_sym]
127
- # hash[r.to_sym] = instance
128
- # end
129
- # hash
130
- end
131
-
132
-
133
- def parse_has_many instance, r, value
134
- # puts " // Parsing #{r.name}, #{value}"
135
- ids = value.split(/\s*,\s*/)
136
- ids.each do |id|
137
- related_instance = Table.get_instance r.class_name, id
138
- # puts ">> Creating a has-many relationship. #{id}, #{related_instance}"
139
- unless related_instance.nil?
140
- instance.send(r.name.to_sym) << related_instance
141
- end
142
- end
143
- end
144
-
145
- def parse_belongs_to instance, r, value
146
- ri = Table.get_instance(r, value)
147
- instance.attributes = { r.name.to_sym => ri }
148
-
149
- # puts "Parsing Belongs_To. #{instance.class} #{instance.to_param} --- #{r.name.to_sym} --- #{ri.class} #{ri.to_param}"
150
- end
151
-
45
+
152
46
  end
153
47
  end
154
48
  end
@@ -1,52 +1,58 @@
1
1
  require 'spreadsheet'
2
2
 
3
3
  module Garden
4
- class Excel
4
+ module Spreadsheets
5
+ class Excel
5
6
 
6
- def initialize filepath
7
- open filepath
8
- end
7
+ def initialize filepath, options={}
8
+ options ||= {}
9
+
10
+ @options = options.reverse_merge! :some_option => "nevermind"
11
+
12
+ open filepath
13
+ end
9
14
 
10
- def open filepath
11
- puts "Planting spreadsheet: #{filepath}"
15
+ def open filepath
16
+ puts "Planting spreadsheet: #{filepath}"
12
17
 
13
- @ss = Spreadsheet.open filepath
14
- @ss.worksheets.each do |table|
15
- puts "Parsing table #{table.name}"
16
- parse_table table
17
- end
18
+ @ss = Spreadsheet.open filepath
19
+ worksheet_names = @options[:only] || @options[:worksheet] || @ss.worksheets.collect { |table| table.name }
20
+ worksheet_names = [worksheet_names] unless worksheet_names.is_a?(Enumerable)
21
+
22
+ # Import the worksheets
23
+ worksheet_names.each do |name|
24
+ puts "Parsing table #{name}"
25
+ parse_table @ss.worksheets.find { |table| table.name == name.to_s }
26
+ end
18
27
 
19
- end
28
+ end
20
29
 
21
- def parse_table table
22
- # The table object passed in is a Spreadsheet::Worksheet instance.
30
+ def parse_table table
31
+ # The table object passed in is a Spreadsheet::Worksheet instance.
23
32
 
24
- table_mediator = Mediators::Table.new table.name
25
- if !table_mediator.valid?
26
- return
27
- end
33
+ table_mediator = Mediators::Table.new table.name
34
+ if !table_mediator.valid?
35
+ return
36
+ end
28
37
 
29
- # Get the headers. These values will be the attribute names
30
- headers = table_mediator.parse_headers table.first.to_a
38
+ # Get the headers. These values will be the attribute names
39
+ headers = table_mediator.parse_headers table.first.to_a
31
40
 
32
- # Now loop the table rows, inserting records.
33
- table.each do |row|
34
- next if row.idx == 0
35
- # puts '...............'
36
-
37
- table_mediator.create_instance parse_worksheet_row(headers, row)
41
+ # Now loop the table rows, inserting records.
42
+ table.each do |row|
43
+ next if row.idx == 0
44
+ table_mediator.create_instance parse_worksheet_row(headers, row)
45
+ end
38
46
  end
39
- end
40
-
41
- def parse_worksheet_row keys, values
42
- h = {}
43
- keys.each_index do |index|
44
- key = keys[index].to_sym
45
- h[key] = values[index]
47
+
48
+ def parse_worksheet_row keys, values
49
+ h = {}
50
+ keys.each_index do |index|
51
+ key = keys[index].to_sym
52
+ h[key] = values[index]
53
+ end
54
+ h
46
55
  end
47
- h
48
56
  end
49
-
50
-
51
57
  end
52
58
  end
@@ -1,3 +1,3 @@
1
1
  module Garden
2
- VERSION = "0.0.4.pre"
2
+ VERSION = "0.0.5.pre"
3
3
  end
data/lib/garden.rb CHANGED
@@ -1,10 +1,13 @@
1
1
  require "garden/version"
2
2
 
3
3
  module Garden
4
-
5
- autoload :Excel, 'garden/spreadsheets'
6
- autoload :Mediators, 'garden/mediators'
7
-
4
+ extend ActiveSupport::Autoload
5
+
6
+ autoload :Spreadsheets
7
+ autoload :Mediators
8
+ autoload :Helpers
9
+ autoload :Instance
10
+
8
11
  # def self.plant
9
12
  # # todo
10
13
  # end
@@ -18,9 +21,9 @@ module Garden
18
21
  # # todo
19
22
  # end
20
23
 
21
- def self.excel file_name_or_path
24
+ def self.excel file_name_or_path, options=nil
22
25
  filepath = resolve_file_path(file_name_or_path)
23
- Excel.new filepath
26
+ Spreadsheets::Excel.new filepath, options
24
27
  end
25
28
 
26
29
  def self.resolve_file_path name_or_path
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: garden
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4.pre
4
+ version: 0.0.5.pre
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2011-09-16 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: spreadsheet
16
- requirement: &70269096817560 !ruby/object:Gem::Requirement
16
+ requirement: &70343008328480 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70269096817560
24
+ version_requirements: *70343008328480
25
25
  description: ! 'Allows you to organize your seeds in different formats. Typical seeds.rb,
26
26
  yaml fixtures, and a variety of spreadsheet formats. '
27
27
  email:
@@ -36,6 +36,9 @@ files:
36
36
  - Rakefile
37
37
  - garden.gemspec
38
38
  - lib/garden.rb
39
+ - lib/garden/helpers.rb
40
+ - lib/garden/helpers/real_instance.rb
41
+ - lib/garden/instance.rb
39
42
  - lib/garden/mediators.rb
40
43
  - lib/garden/spreadsheets.rb
41
44
  - lib/garden/version.rb