csvash 0.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +15 -3
- data/lib/csvash.rb +34 -47
- data/lib/csvash/version.rb +1 -1
- data/lib/generators/initializer/templates/csvash.rb +4 -2
- data/test/modelifying_test.rb +22 -13
- data/test/overrides_test.rb +13 -0
- data/test/test_helper.rb +0 -1
- metadata +4 -2
data/README.md
CHANGED
|
@@ -36,12 +36,24 @@ To get a collection of hashes containing the csv data you can call:
|
|
|
36
36
|
Csvash.hashify '/path/of/your/file.csv'
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
Note: You can use `modelify_and_export` or `modelify_and_import` methods to generate or parse csv files respectively.
|
|
40
|
+
|
|
41
|
+
In order to export, you can pass the desired path and CSV filename. Finally, you can pass a collection of already filled objects from a specific class you can pass the array:
|
|
40
42
|
|
|
41
43
|
```ruby
|
|
42
|
-
Csvash.
|
|
44
|
+
Csvash.modelify_and_export '/path/to/file.csv', collection
|
|
43
45
|
```
|
|
44
46
|
|
|
47
|
+
_Where **collection** is an array of User objects, for example_
|
|
48
|
+
|
|
49
|
+
However, to import from a csv file you can pass the path where the file is allocated and a class, as usual:
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
Csvash.modelify_and_import '/path/of/your/file.csv', User
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
_* The path and its directories are created automatically_
|
|
56
|
+
|
|
45
57
|
##Options
|
|
46
58
|
|
|
47
59
|
There are some behavior options that can be changed with its initializer. To create it just type:
|
|
@@ -54,7 +66,7 @@ These are the avaiable options
|
|
|
54
66
|
|
|
55
67
|
```ruby
|
|
56
68
|
# If set to true it will only retain fields that matches the class to be filled. Default is false.
|
|
57
|
-
#
|
|
69
|
+
# config.mass_assignment_safe = true
|
|
58
70
|
```
|
|
59
71
|
|
|
60
72
|
## Contributing
|
data/lib/csvash.rb
CHANGED
|
@@ -1,39 +1,34 @@
|
|
|
1
1
|
require 'csvash/version'
|
|
2
2
|
require 'csv'
|
|
3
|
-
require 'fileutils'
|
|
4
3
|
|
|
5
4
|
module Csvash
|
|
6
5
|
class << self; attr_accessor :mass_assignment_safe end
|
|
6
|
+
@@mass_assignment_safe = false
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
warn "[DEPRECATION] `import_from_path` is deprecated. Please use `hashify` instead."
|
|
11
|
-
hashify path
|
|
8
|
+
def self.setup
|
|
9
|
+
yield self
|
|
12
10
|
end
|
|
13
11
|
|
|
12
|
+
def self.respond_to?(method)
|
|
13
|
+
(method =~ /^modelify_and_\w+$/) || super
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
14
17
|
def self.hashify(path)
|
|
15
18
|
import path do |collection, current_line|
|
|
16
19
|
collection << current_line
|
|
17
20
|
end
|
|
18
21
|
end
|
|
19
22
|
|
|
20
|
-
# <b>DEPRECATED:</b> Please use <tt>modelify_and_export</tt> or <tt>modelify_and_import</tt> instead.
|
|
21
23
|
def self.modelify(path, klass, *args)
|
|
22
24
|
klass = klass.to_s.classify.constantize if klass.is_a?(String) || klass.is_a?(Symbol)
|
|
23
25
|
method = args.first
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
handle_mass_assignment(klass, current_line)
|
|
28
|
-
collection << klass.new(current_line)
|
|
29
|
-
end
|
|
30
|
-
else
|
|
26
|
+
self.public_send method, path, klass do |collection, current_line|
|
|
27
|
+
handle_mass_assignment(klass, current_line)
|
|
28
|
+
collection << klass.new(current_line)
|
|
31
29
|
end
|
|
32
30
|
end
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
|
|
37
32
|
def self.import(path, *optionals, &block)
|
|
38
33
|
cols = nil
|
|
39
34
|
collection = []
|
|
@@ -55,40 +50,32 @@ private
|
|
|
55
50
|
collection
|
|
56
51
|
end
|
|
57
52
|
|
|
58
|
-
def self.handle_mass_assignment(klass, line)
|
|
59
|
-
if mass_assignment_safe
|
|
60
|
-
attr_cols = klass.instance_methods(false)
|
|
61
|
-
line = line.delete_if {|col| !attr_cols.include? col}
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
53
|
# generates a csv file into a given path
|
|
66
54
|
# a path must be given (ex: *path/to/file.csv)
|
|
67
55
|
def self.export(file, collection, &block)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
fields = ""
|
|
56
|
+
file = full_path(file)
|
|
57
|
+
|
|
71
58
|
unless collection.empty?
|
|
72
|
-
|
|
73
|
-
collection.first.class.instance_methods(false).delete_if {|m| rows << m unless m.to_s.include?"=" }
|
|
59
|
+
headers = retrieve_headers collection
|
|
74
60
|
begin
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
csv << rows
|
|
61
|
+
CSV.open(file, 'wb', :col_sep => "\;") do |csv|
|
|
62
|
+
csv << headers
|
|
78
63
|
collection.each do |item|
|
|
79
|
-
|
|
80
|
-
rows.each {|attribute| lines << item.send(attribute)}
|
|
81
|
-
csv << lines
|
|
64
|
+
csv << retrieve_fields(item, headers)
|
|
82
65
|
end
|
|
83
|
-
csv_return = csv
|
|
84
66
|
end
|
|
85
|
-
csv_return
|
|
86
67
|
rescue Errno::ENOENT => e
|
|
87
68
|
puts e
|
|
88
69
|
end
|
|
89
70
|
end
|
|
90
71
|
end
|
|
91
72
|
|
|
73
|
+
def self.handle_mass_assignment(klass, line)
|
|
74
|
+
if mass_assignment_safe
|
|
75
|
+
attr_cols = klass.instance_methods(false)
|
|
76
|
+
line = line.delete_if { |col| !attr_cols.include? col }
|
|
77
|
+
end
|
|
78
|
+
end
|
|
92
79
|
|
|
93
80
|
# shifts the method calling towards export() or import()
|
|
94
81
|
# ex: modelify_and_import("path/to/file.csv", collection), modelify_and_export("path/to/custom_filename.csv", collection)
|
|
@@ -97,22 +84,22 @@ private
|
|
|
97
84
|
Csvash.public_send(:modelify, *args, $1)
|
|
98
85
|
end
|
|
99
86
|
|
|
100
|
-
# overriding respond_to method
|
|
101
|
-
def respond_to?(method)
|
|
102
|
-
(method =~ /^modelify_and_(\w+)$/) || super
|
|
103
|
-
end
|
|
104
|
-
|
|
105
87
|
# creates the full path
|
|
106
88
|
def self.full_path(file)
|
|
107
89
|
splitted = file.split("/")
|
|
108
90
|
current_file = file.split("/").last
|
|
109
91
|
current_path = splitted.shift(splitted.size-1)
|
|
110
92
|
current_full_path = current_path.join("/") + "/"
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
93
|
+
|
|
94
|
+
FileUtils.mkdir_p(current_full_path) unless File.directory? current_full_path
|
|
95
|
+
current_full_path.concat current_file
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def self.retrieve_headers collection
|
|
99
|
+
collection.first.class.instance_methods(false).select { |m| m.to_s !~ /=$/ }
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def self.retrieve_fields item, headers
|
|
103
|
+
headers.map { |attribute| item.public_send(attribute) }
|
|
117
104
|
end
|
|
118
105
|
end
|
data/lib/csvash/version.rb
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
#
|
|
1
|
+
Csvash.setup do |config|
|
|
2
|
+
# If set to true it will only retain fields that matches the class to be filled. Default is false.
|
|
3
|
+
# config.mass_assignment_safe = true
|
|
4
|
+
end
|
data/test/modelifying_test.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
require 'minitest/spec'
|
|
2
2
|
require 'minitest/autorun'
|
|
3
|
-
require 'fileutils'
|
|
4
3
|
require 'csvash'
|
|
5
4
|
require "./test/test_helper"
|
|
6
5
|
|
|
@@ -23,24 +22,34 @@ describe 'Modelifying' do
|
|
|
23
22
|
end
|
|
24
23
|
|
|
25
24
|
it "Mass assignment Safe Mode ON" do
|
|
26
|
-
Csvash.mass_assignment_safe = true
|
|
25
|
+
Csvash.setup { |config| config.mass_assignment_safe = true }
|
|
27
26
|
cars_extracted = Csvash.modelify_and_import fetch_fixture_path('example_mass_assignment.csv'), Car
|
|
28
27
|
end
|
|
29
28
|
end
|
|
30
29
|
describe "export" do
|
|
30
|
+
before :each do
|
|
31
|
+
Dir.mkdir(fetch_fixture_path('tmp'))
|
|
32
|
+
end
|
|
33
|
+
after :each do
|
|
34
|
+
FileUtils.rm_rf fetch_fixture_path('tmp')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
let(:cars_path) { fetch_fixture_path('tmp/cars.csv') }
|
|
38
|
+
|
|
31
39
|
it "passing a collection of Car object" do
|
|
32
40
|
cars = []
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
cars_exported.
|
|
43
|
-
|
|
41
|
+
3.times do
|
|
42
|
+
cars << Car.new(
|
|
43
|
+
year: '1997',
|
|
44
|
+
make: 'Ford',
|
|
45
|
+
model: 'E350',
|
|
46
|
+
description: 'ac, abs, moon',
|
|
47
|
+
price: '3000.00'
|
|
48
|
+
)
|
|
49
|
+
end
|
|
50
|
+
cars_exported = Csvash.modelify_and_export cars_path, cars
|
|
51
|
+
File.exists?(cars_path).must_equal true
|
|
52
|
+
File.stat(cars_path).size.must_equal 145
|
|
44
53
|
end
|
|
45
54
|
end
|
|
46
55
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'minitest/spec'
|
|
2
|
+
require 'minitest/autorun'
|
|
3
|
+
require 'csvash'
|
|
4
|
+
require "./test/test_helper"
|
|
5
|
+
|
|
6
|
+
include TestHelper
|
|
7
|
+
|
|
8
|
+
describe 'Overrides' do
|
|
9
|
+
it "checks for the import and export methods existence" do
|
|
10
|
+
Csvash.respond_to?('modelify_and_import').wont_equal false
|
|
11
|
+
Csvash.respond_to?('modelify_and_export').wont_equal false
|
|
12
|
+
end
|
|
13
|
+
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: csvash
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2012-09-
|
|
13
|
+
date: 2012-09-27 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: rake
|
|
@@ -60,6 +60,7 @@ files:
|
|
|
60
60
|
- test/fixtures/example_values.txt
|
|
61
61
|
- test/hashifying_test.rb
|
|
62
62
|
- test/modelifying_test.rb
|
|
63
|
+
- test/overrides_test.rb
|
|
63
64
|
- test/test_helper.rb
|
|
64
65
|
homepage: https://github.com/lukasalexandre/csvash
|
|
65
66
|
licenses: []
|
|
@@ -94,4 +95,5 @@ test_files:
|
|
|
94
95
|
- test/fixtures/example_values.txt
|
|
95
96
|
- test/hashifying_test.rb
|
|
96
97
|
- test/modelifying_test.rb
|
|
98
|
+
- test/overrides_test.rb
|
|
97
99
|
- test/test_helper.rb
|