acts_as_importable 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem "activerecord", "~> 3.0.3"
7
+ gem "actionpack", "~> 3.0.3"
8
+ gem "fastercsv", "~> 1.5.3"
9
+
10
+ # Add dependencies to develop your gem here.
11
+ # Include everything needed to run rake, tests, features, etc.
12
+ group :development do
13
+ gem "bundler", "~> 1.0.0"
14
+ gem "jeweler", "~> 1.5.2"
15
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,52 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ abstract (1.0.0)
5
+ actionpack (3.0.3)
6
+ activemodel (= 3.0.3)
7
+ activesupport (= 3.0.3)
8
+ builder (~> 2.1.2)
9
+ erubis (~> 2.6.6)
10
+ i18n (~> 0.4)
11
+ rack (~> 1.2.1)
12
+ rack-mount (~> 0.6.13)
13
+ rack-test (~> 0.5.6)
14
+ tzinfo (~> 0.3.23)
15
+ activemodel (3.0.3)
16
+ activesupport (= 3.0.3)
17
+ builder (~> 2.1.2)
18
+ i18n (~> 0.4)
19
+ activerecord (3.0.3)
20
+ activemodel (= 3.0.3)
21
+ activesupport (= 3.0.3)
22
+ arel (~> 2.0.2)
23
+ tzinfo (~> 0.3.23)
24
+ activesupport (3.0.3)
25
+ arel (2.0.6)
26
+ builder (2.1.2)
27
+ erubis (2.6.6)
28
+ abstract (>= 1.0.0)
29
+ fastercsv (1.5.3)
30
+ git (1.2.5)
31
+ i18n (0.5.0)
32
+ jeweler (1.5.2)
33
+ bundler (~> 1.0.0)
34
+ git (>= 1.2.5)
35
+ rake
36
+ rack (1.2.1)
37
+ rack-mount (0.6.13)
38
+ rack (>= 1.0.0)
39
+ rack-test (0.5.6)
40
+ rack (>= 1.0)
41
+ rake (0.8.7)
42
+ tzinfo (0.3.23)
43
+
44
+ PLATFORMS
45
+ ruby
46
+
47
+ DEPENDENCIES
48
+ actionpack (~> 3.0.3)
49
+ activerecord (~> 3.0.3)
50
+ bundler (~> 1.0.0)
51
+ fastercsv (~> 1.5.3)
52
+ jeweler (~> 1.5.2)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Jagdeep Singh
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
@@ -0,0 +1,90 @@
1
+ = ActsAsImportable
2
+
3
+ ActsAsImportable makes import/export of ActiveRecord models from csv files easier and less repetitive. It helps keep your code DRY, clean, and simple.
4
+
5
+ == Usage
6
+
7
+ === Add the following to your controller:
8
+
9
+ acts_as_importable :product
10
+
11
+ If model name is not specified, it will use the controller name to find the model name. So, the following is same as above if the controller name is "products"
12
+
13
+ acts_as_importable
14
+
15
+ ==== Scoping imported objects:
16
+
17
+ acts_as_importable :product, :scoped => :current_store
18
+
19
+ This will import all material records within the current_store object returned by the controller#current_store method. Product should have a belongs_to association to Store for this feature to work.
20
+
21
+ === Add the following to your Model:
22
+
23
+ acts_as_importable :import_fields => ["name", "price"]
24
+
25
+ This will populate the specified fields while importing the model records from csv.
26
+
27
+ acts_as_importable :import_fields => ["name", "price", "product_type.name"]
28
+
29
+ If there is a field which is not a direct attribute or is an association eg. 'product_type.name' in the example above, you have to define a method like the following and it will be called while importing the data:
30
+
31
+ def assign_product_type(data_row)
32
+ name = data_row[2].strip
33
+ product_type = ProductType.find_by_name(name)
34
+ self.product_type_id = product_type.id if product_type
35
+ end
36
+
37
+ NOTE: Any field which has a '.' in its name require a method with name like "assign_#{name_of_the_field}". Also as a parameter you get the entire row from the csv file. So you can operate on multiple columns to generate the value for this field.
38
+
39
+ Another example of the method above:
40
+
41
+ def assign_category(data_row)
42
+ category = Category.find_by_name(data_row[3].strip)
43
+ self.category_id = category.id if category
44
+ end
45
+
46
+ ==== Customizing the export fields:
47
+
48
+ You can specify a different list of fields to export if you want them to be different from the import fields e.g.
49
+
50
+ acts_as_importable :import_fields => ["name", "price", "product_type.name"],
51
+ :export_fields => ["name", "product_type.name"]
52
+
53
+ === Add the following routes to your routes.rb:
54
+
55
+ resources :products do
56
+ collection do
57
+ post 'upload'
58
+ get 'import'
59
+ get 'export'
60
+ end
61
+ end
62
+
63
+ === Define the following constant (e.g. in an initializer):
64
+
65
+ UPLOADS_PATH = "#{Rails.root}/tmp/uploads"
66
+
67
+ NOTE: This can be any file system path writable by the Rails process.
68
+
69
+ == Contributing to acts_as_importable
70
+
71
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
72
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
73
+ * Fork the project
74
+ * Start a feature/bugfix branch
75
+ * Commit and push until you are happy with your contribution
76
+ * Make sure to add tests for it in the test/test_acts_as_importable project. This is important so I don't break it in a future version unintentionally.
77
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
78
+
79
+ == Credit
80
+
81
+ A big thanks goes to -
82
+
83
+ * {Ennova}[http://ennova.com.au] for giving us an opportunity to extract and release this functionality as a gem for the larger community
84
+ * {Bhavin Javia}[http://github.com/bhavinjavia] for helping with extracting, enhancing and releasing this gem
85
+
86
+ == Copyright
87
+
88
+ Copyright (c) 2010 Jagdeep Singh. See LICENSE.txt for
89
+ further details.
90
+
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
+ gem.name = "acts_as_importable"
16
+ gem.version = File.exist?('VERSION') ? File.read('VERSION') : ""
17
+ gem.homepage = "https://github.com/Ennova/acts_as_importable"
18
+ gem.license = "MIT"
19
+ gem.summary = %Q{Makes your model importable from .csv and exportable to .csv}
20
+ gem.description = %Q{Use this gem to add import/export to .csv functionality to your activerecord models}
21
+ gem.email = "jagdeepkh@gmail.com"
22
+ gem.authors = ["Jagdeep Singh"]
23
+ gem.files.exclude 'test'
24
+ gem.files.exclude '.rvmrc'
25
+ gem.files.exclude '.document'
26
+ gem.test_files.exclude 'test'
27
+ end
28
+
29
+ Jeweler::RubygemsDotOrgTasks.new
30
+
31
+ require 'rake/rdoctask'
32
+ Rake::RDocTask.new do |rdoc|
33
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
34
+
35
+ rdoc.rdoc_dir = 'rdoc'
36
+ rdoc.title = "acts_as_importable #{version}"
37
+ rdoc.rdoc_files.include('README*')
38
+ rdoc.rdoc_files.include('lib/**/*.rb')
39
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,65 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{acts_as_importable}
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jagdeep Singh"]
12
+ s.date = %q{2011-01-02}
13
+ s.description = %q{Use this gem to add import/export to .csv functionality to your activerecord models}
14
+ s.email = %q{jagdeepkh@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "LICENSE.txt",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "acts_as_importable.gemspec",
27
+ "lib/acts_as_importable.rb",
28
+ "lib/import_export.rb",
29
+ "lib/import_export/controller_methods.rb",
30
+ "lib/import_export/routing.rb",
31
+ "lib/tasks/import_export.rake",
32
+ "views/import_export/import.html.erb"
33
+ ]
34
+ s.homepage = %q{https://github.com/Ennova/acts_as_importable}
35
+ s.licenses = ["MIT"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = %q{1.3.7}
38
+ s.summary = %q{Makes your model importable from .csv and exportable to .csv}
39
+
40
+ if s.respond_to? :specification_version then
41
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
42
+ s.specification_version = 3
43
+
44
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
45
+ s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.3"])
46
+ s.add_runtime_dependency(%q<actionpack>, ["~> 3.0.3"])
47
+ s.add_runtime_dependency(%q<fastercsv>, ["~> 1.5.3"])
48
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
49
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
50
+ else
51
+ s.add_dependency(%q<activerecord>, ["~> 3.0.3"])
52
+ s.add_dependency(%q<actionpack>, ["~> 3.0.3"])
53
+ s.add_dependency(%q<fastercsv>, ["~> 1.5.3"])
54
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
55
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
56
+ end
57
+ else
58
+ s.add_dependency(%q<activerecord>, ["~> 3.0.3"])
59
+ s.add_dependency(%q<actionpack>, ["~> 3.0.3"])
60
+ s.add_dependency(%q<fastercsv>, ["~> 1.5.3"])
61
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
62
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
63
+ end
64
+ end
65
+
@@ -0,0 +1,12 @@
1
+ require "active_record"
2
+ require "action_controller"
3
+ require "fastercsv"
4
+
5
+ require 'import_export'
6
+ ActiveRecord::Base.send :include, ImportExport::ModelMethods
7
+
8
+ # require 'import_export/routing'
9
+ # ActionC::Routing::RouteSet::Mapper.send :include, ImportExport::Routing
10
+
11
+ require 'import_export/controller_methods'
12
+ ActionController::Base.send :include, ImportExport::ControllerMethods
@@ -0,0 +1,74 @@
1
+ # ImportExport
2
+ module ImportExport
3
+ module ControllerMethods
4
+
5
+ def self.included(base)
6
+ base.send :extend, ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ # any method placed here will apply to classes
11
+ def acts_as_importable(model_class_name = nil, context = {})
12
+ cattr_accessor :model_class
13
+ cattr_accessor :context
14
+ if model_class_name
15
+ self.model_class = model_class_name.to_s.classify.constantize
16
+ else
17
+ self.model_class = self.controller_name.singularize.classify.constantize
18
+ end
19
+ self.context = context
20
+ send :include, InstanceMethods
21
+ end
22
+ end
23
+
24
+ module InstanceMethods
25
+ def export
26
+ send_data self.class.model_class.export, :type => 'text/csv; charset=iso-8859-1; header=present', :disposition => "attachment; filename=#{export_file_name}"
27
+ end
28
+
29
+ def import
30
+ @new_objects = []
31
+ filename = "#{UPLOADS_PATH}/#{self.controller_name}.csv"
32
+ context = {}
33
+ self.class.context.each_pair do |key, value|
34
+ context[key] = self.send(value)
35
+ end
36
+
37
+ if File.exists? filename
38
+ begin
39
+ @new_objects = self.class.model_class.import(filename, context)
40
+ flash[:notice] = "Import Successful - #{@new_objects.length} New #{self.class.model_class.name.underscore.humanize.pluralize}"
41
+ rescue Exception => e
42
+ logger.error "Error: Unable to process file. #{e}"
43
+ flash[:error] = "Error: Unable to process file. #{e}"
44
+ ensure
45
+ File.delete(filename)
46
+ end
47
+ else
48
+ @new_objects = []
49
+ end
50
+ render :template => "import_export/import"
51
+ end
52
+
53
+ def upload
54
+ require 'ftools'
55
+ if params[:csv_file] && File.extname(params[:csv_file].original_filename) == '.csv'
56
+ File.makedirs "#{UPLOADS_PATH}"
57
+ File.open("#{UPLOADS_PATH}/#{self.controller_name}.csv", "wb") { |f| f.write(params[:csv_file].read)}
58
+ flash[:notice] = "Successful import of #{self.controller_name} data file"
59
+ else
60
+ flash[:error] = "Error! Invalid file, please select a csv file."
61
+ end
62
+ redirect_to "/#{self.controller_name}/import"
63
+ end
64
+
65
+ private
66
+
67
+ def export_file_name
68
+ "#{Time.now.to_formatted_s(:number)}_#{self.controller_name}_export.csv"
69
+ end
70
+
71
+ end # end of module InstanceMethods
72
+
73
+ end # end of module ControllerMethods
74
+ end
@@ -0,0 +1,7 @@
1
+ module ImportExport
2
+ module Routing
3
+ def import_export
4
+ # @set.add_route("/materials/import", {:controller => "materials", :action => "import"})
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,135 @@
1
+ # ImportExport
2
+ module ImportExport
3
+ module ModelMethods
4
+ def self.included(base)
5
+ base.send :extend, ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ # any method placed here will apply to classes
10
+ def acts_as_importable(options = {})
11
+ cattr_accessor :import_fields, :export_fields
12
+ self.import_fields = options[:import_fields]
13
+ self.export_fields = options[:export_fields]
14
+ send :include, InstanceMethods
15
+ end
16
+
17
+ def import(filename, context)
18
+
19
+ collection = []
20
+ headers, *data = self.read_csv(filename)
21
+ scope_object = context[:scoped]
22
+
23
+ ActiveRecord::Base.transaction do
24
+ data.each_with_index do |data_row, index|
25
+ data_row.map{|d| d.strip! if d}
26
+ Rails.logger.info data_row.inspect
27
+
28
+ begin
29
+ element = self.new
30
+ element.send("#{scope_object.class.name.downcase}=", scope_object) if scope_object
31
+
32
+ self.import_fields.each_with_index do |field_name, field_index|
33
+ if field_name.include?('.')
34
+ method_name = 'assign_' + field_name.split('.')[0]
35
+ if element.respond_to?(method_name)
36
+ element.send method_name, data_row
37
+ elsif element.respond_to?("#{field_name.split('.')[0]}_id")
38
+ create_record = field_name.include?('!')
39
+ split_field = field_name.gsub(/!/,'').split('.').compact
40
+ initial_class = split_field[0].classify.constantize
41
+ if initial_class and initial_class.respond_to?("find_by_#{split_field[1]}")
42
+ begin
43
+ e = initial_class.send("find_by_#{split_field[1]}", data_row[field_index])
44
+ rescue
45
+ e = nil
46
+ end
47
+ # try to create a new record if not found in database and if '!' is present
48
+ if e.nil? and create_record and !data_row[field_index].blank?
49
+ e = initial_class.create!("#{split_field[1]}" => data_row[field_index])
50
+ end
51
+ if e.kind_of?(ActiveRecord::Base)
52
+ element["#{split_field[0]}_id"] = e.id
53
+ end
54
+ else
55
+ e = nil
56
+ end
57
+ end
58
+ else
59
+ element.send "#{field_name}=", data_row[field_index]
60
+ end
61
+ end
62
+
63
+ element.save!
64
+ collection << element
65
+ rescue Exception => e
66
+ Rails.logger.error "Invalid data found at line #{index + 2} !!!"
67
+ Rails.logger.error e.message
68
+ Rails.logger.error e.backtrace.join("\n")
69
+ raise e
70
+ end
71
+ end
72
+ end
73
+ return collection
74
+ end
75
+
76
+ def export
77
+ export_fields = self.import_fields || self.export_fields
78
+ FasterCSV.generate do |csv|
79
+ csv << export_fields.map{|f| f.split('.')[0]}
80
+
81
+ self.find_each(:batch_size => 2000) do |element|
82
+ collection = []
83
+ export_fields.each do |field_name|
84
+ begin
85
+ if field_name.include?('.')
86
+ method_names = field_name.gsub(/!/,'').split('.').compact
87
+ sub_element = element
88
+ method_names.each do |method_name|
89
+ if sub_element || sub_element.respond_to?(method_name)
90
+ sub_element = sub_element.send(method_name)
91
+ else
92
+ break
93
+ end
94
+ end
95
+ collection << sub_element
96
+ else
97
+ collection << element.send(field_name)
98
+ end
99
+ rescue Exception => e
100
+ Rails.logger.info ">>>>>>>>> Exception Caught ImportExport >>>>>>>>>>>"
101
+ Rails.logger.error e.message
102
+ Rails.logger.error e.backtrace
103
+ collection << nil
104
+ end
105
+ end
106
+ csv << collection
107
+ end
108
+
109
+ end
110
+ end
111
+
112
+ def read_csv(filename)
113
+ if File.exist?(filename)
114
+ begin
115
+ collection = FasterCSV.parse(File.open(filename, 'rb'))
116
+ rescue FasterCSV::MalformedCSVError => e
117
+ raise e
118
+ end
119
+
120
+ collection = collection.map{|w| w} unless collection.nil?
121
+ collection = [] if collection.nil?
122
+
123
+ return collection
124
+ else
125
+ raise ArgumentError, "File does not exist."
126
+ end
127
+ end
128
+ end
129
+
130
+ module InstanceMethods
131
+ # any method placed here will apply to instaces, like @hickwall
132
+ end
133
+
134
+ end
135
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :import_export do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,14 @@
1
+ <h1>Import <%=controller.controller_name.capitalize%></h1>
2
+
3
+
4
+ <% form_tag "/#{controller.controller_name}/upload",
5
+ :multipart => true, :onsubmit => "Element.show('loading')" do %>
6
+ <%= file_field_tag 'csv_file', :style => 'width:220px;' %>
7
+ <% if @new_objects.empty? %>
8
+ <%= submit_tag 'Import', :class => 'long' %>
9
+ <% else %>
10
+ <%= submit_tag 'Import', :class => 'long', :confirm => "Are you sure you wish to re-import?" %>
11
+ <% end %>
12
+ <% end %>
13
+
14
+ <p><%= link_to 'Back', "/#{controller.controller_name}" %></p>
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: acts_as_importable
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
+ platform: ruby
12
+ authors:
13
+ - Jagdeep Singh
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-01-02 00:00:00 +05:30
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ type: :runtime
24
+ name: activerecord
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ hash: 1
31
+ segments:
32
+ - 3
33
+ - 0
34
+ - 3
35
+ version: 3.0.3
36
+ requirement: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ prerelease: false
39
+ type: :runtime
40
+ name: actionpack
41
+ version_requirements: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ hash: 1
47
+ segments:
48
+ - 3
49
+ - 0
50
+ - 3
51
+ version: 3.0.3
52
+ requirement: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ prerelease: false
55
+ type: :runtime
56
+ name: fastercsv
57
+ version_requirements: &id003 !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ hash: 5
63
+ segments:
64
+ - 1
65
+ - 5
66
+ - 3
67
+ version: 1.5.3
68
+ requirement: *id003
69
+ - !ruby/object:Gem::Dependency
70
+ prerelease: false
71
+ type: :development
72
+ name: bundler
73
+ version_requirements: &id004 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ hash: 23
79
+ segments:
80
+ - 1
81
+ - 0
82
+ - 0
83
+ version: 1.0.0
84
+ requirement: *id004
85
+ - !ruby/object:Gem::Dependency
86
+ prerelease: false
87
+ type: :development
88
+ name: jeweler
89
+ version_requirements: &id005 !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ hash: 7
95
+ segments:
96
+ - 1
97
+ - 5
98
+ - 2
99
+ version: 1.5.2
100
+ requirement: *id005
101
+ description: Use this gem to add import/export to .csv functionality to your activerecord models
102
+ email: jagdeepkh@gmail.com
103
+ executables: []
104
+
105
+ extensions: []
106
+
107
+ extra_rdoc_files:
108
+ - LICENSE.txt
109
+ - README.rdoc
110
+ files:
111
+ - Gemfile
112
+ - Gemfile.lock
113
+ - LICENSE.txt
114
+ - README.rdoc
115
+ - Rakefile
116
+ - VERSION
117
+ - acts_as_importable.gemspec
118
+ - lib/acts_as_importable.rb
119
+ - lib/import_export.rb
120
+ - lib/import_export/controller_methods.rb
121
+ - lib/import_export/routing.rb
122
+ - lib/tasks/import_export.rake
123
+ - views/import_export/import.html.erb
124
+ has_rdoc: true
125
+ homepage: https://github.com/Ennova/acts_as_importable
126
+ licenses:
127
+ - MIT
128
+ post_install_message:
129
+ rdoc_options: []
130
+
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ none: false
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ hash: 3
139
+ segments:
140
+ - 0
141
+ version: "0"
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ none: false
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ hash: 3
148
+ segments:
149
+ - 0
150
+ version: "0"
151
+ requirements: []
152
+
153
+ rubyforge_project:
154
+ rubygems_version: 1.3.7
155
+ signing_key:
156
+ specification_version: 3
157
+ summary: Makes your model importable from .csv and exportable to .csv
158
+ test_files: []
159
+