csv_record 1.4.0 → 1.5.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 +52 -1
- data/csv_record.gemspec +2 -0
- data/lib/csv_record/associations.rb +31 -0
- data/lib/csv_record/document.rb +8 -7
- data/lib/csv_record/helpers.rb +24 -0
- data/lib/csv_record/reader.rb +9 -5
- data/lib/csv_record/version.rb +1 -1
- data/lib/csv_record/writer.rb +11 -2
- data/test/csv_record/associations_test.rb +48 -0
- data/test/csv_record/reader_test.rb +8 -1
- data/test/csv_record/writer_test.rb +1 -1
- data/test/models/jedi.rb +15 -0
- data/test/models/jedi_order.rb +15 -0
- data/test/test_helper.rb +25 -0
- metadata +25 -2
data/README.md
CHANGED
@@ -27,10 +27,12 @@ $ gem install csv_record
|
|
27
27
|
## Usage
|
28
28
|
|
29
29
|
```ruby
|
30
|
-
|
30
|
+
require 'csv_record'
|
31
31
|
|
32
32
|
class Car
|
33
33
|
include CsvRecord::Document
|
34
|
+
|
35
|
+
attr_accessor :year, :make, :model, :description, :price
|
34
36
|
end
|
35
37
|
```
|
36
38
|
|
@@ -70,6 +72,54 @@ Car.first # retrieves the first record in the database
|
|
70
72
|
Car.last # retrieves the last record in the database
|
71
73
|
```
|
72
74
|
|
75
|
+
##Associations
|
76
|
+
###Belongs To
|
77
|
+
A Belongs To association can be declared through the following method:
|
78
|
+
```ruby
|
79
|
+
class Company
|
80
|
+
include CsvRecord::Document
|
81
|
+
|
82
|
+
attr_accessor :name
|
83
|
+
end
|
84
|
+
|
85
|
+
class Car
|
86
|
+
include CsvRecord::Document
|
87
|
+
|
88
|
+
belongs_to :company
|
89
|
+
end
|
90
|
+
|
91
|
+
company = Company.create :name => 'Chuts'
|
92
|
+
|
93
|
+
car = Car.new :model => 'F450'
|
94
|
+
|
95
|
+
car.company = company
|
96
|
+
# or
|
97
|
+
car.company_id = company.id
|
98
|
+
|
99
|
+
car.save
|
100
|
+
|
101
|
+
car.company # #<Company:0x007f9b249b24d8>
|
102
|
+
```
|
103
|
+
|
104
|
+
###Has Many
|
105
|
+
Extending the previous example, you can use the `has_many` method to stablish the inverse relationship:
|
106
|
+
```ruby
|
107
|
+
class Company
|
108
|
+
include CsvRecord::Document
|
109
|
+
|
110
|
+
has_many :cars
|
111
|
+
|
112
|
+
attr_accessor :name
|
113
|
+
end
|
114
|
+
|
115
|
+
company = Company.create :name => 'Chutz'
|
116
|
+
|
117
|
+
car.company = company
|
118
|
+
car.save
|
119
|
+
|
120
|
+
company.cars # [#<Car:0x007f9b249b24d8>]
|
121
|
+
```
|
122
|
+
|
73
123
|
##Callbacks
|
74
124
|
Callbacks can be used to execute code on predetermined moments.
|
75
125
|
|
@@ -82,6 +132,7 @@ after_create do |obj|
|
|
82
132
|
obj.do_something
|
83
133
|
end
|
84
134
|
```
|
135
|
+
`obj` refers to the instance you are in
|
85
136
|
|
86
137
|
##Precautions
|
87
138
|
CsvRecord creates a `db` folder in the root of your application. Be sure that it has permission to do so.
|
data/csv_record.gemspec
CHANGED
@@ -15,6 +15,8 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = CsvRecord::VERSION
|
17
17
|
|
18
|
+
gem.add_dependency 'activesupport'
|
19
|
+
|
18
20
|
gem.add_development_dependency 'rake'
|
19
21
|
gem.add_development_dependency 'timecop'
|
20
22
|
gem.add_development_dependency 'turn'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module CsvRecord
|
2
|
+
module Associations
|
3
|
+
def belongs_to(klass)
|
4
|
+
klass_name = klass.to_s
|
5
|
+
|
6
|
+
self.class_eval do
|
7
|
+
self.send :attr_writer, "#{klass}_id"
|
8
|
+
|
9
|
+
define_method klass do
|
10
|
+
klass_name.to_class.find self.id
|
11
|
+
end
|
12
|
+
define_method "#{klass}=" do |value|
|
13
|
+
self.send "#{klass}_id=", value.to_param
|
14
|
+
end
|
15
|
+
define_method "#{klass}_id" do
|
16
|
+
eval("@#{klass}_id").to_i
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def has_many(klass)
|
22
|
+
klass_name = klass.to_s
|
23
|
+
|
24
|
+
self.class_eval do
|
25
|
+
define_method klass do
|
26
|
+
klass_name.to_class.where :"#{self.underscored_class_name}_id" => self.id
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/csv_record/document.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections.rb'
|
2
|
+
|
1
3
|
require 'csv_record/connector'
|
2
4
|
require 'csv_record/writer'
|
3
5
|
require 'csv_record/reader'
|
4
6
|
require 'csv_record/timestamps'
|
5
7
|
require 'csv_record/callbacks'
|
6
8
|
require 'csv_record/helpers'
|
9
|
+
require 'csv_record/associations'
|
7
10
|
|
8
11
|
module CsvRecord
|
9
12
|
|
@@ -11,21 +14,19 @@ module CsvRecord
|
|
11
14
|
# the database.
|
12
15
|
module Document
|
13
16
|
def self.included(receiver)
|
14
|
-
|
15
|
-
|
17
|
+
klass = receiver.name
|
18
|
+
|
19
|
+
receiver.const_set 'DATABASE_LOCATION',"db/#{klass.underscore.pluralize}.csv"
|
20
|
+
receiver.const_set 'DATABASE_LOCATION_TMP',"db/#{klass.underscore.pluralize}_tmp.csv"
|
16
21
|
|
17
22
|
receiver.extend CsvRecord::Connector
|
18
23
|
receiver.extend CsvRecord::Writer::ClassMethods
|
19
24
|
receiver.extend CsvRecord::Reader::ClassMethods
|
25
|
+
receiver.extend CsvRecord::Associations
|
20
26
|
receiver.send :include, CsvRecord::Writer::InstanceMethods
|
21
27
|
receiver.send :include, CsvRecord::Reader::InstanceMethods
|
22
28
|
receiver.send :include, CsvRecord::Timestamps
|
23
29
|
receiver.send :include, CsvRecord::Callbacks
|
24
30
|
end
|
25
|
-
|
26
|
-
def self.parse_caller(at)
|
27
|
-
/(?:(\<class\:)(\w+))/ =~ at
|
28
|
-
$2
|
29
|
-
end
|
30
31
|
end
|
31
32
|
end
|
data/lib/csv_record/helpers.rb
CHANGED
@@ -8,4 +8,28 @@ class Object
|
|
8
8
|
self.to_s =~ /^\d+\.\d+$/
|
9
9
|
!$0.empty?
|
10
10
|
end
|
11
|
+
|
12
|
+
def to_param
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def underscored_class_name
|
17
|
+
self.class.name.underscore
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class String
|
22
|
+
def constantize
|
23
|
+
self.split('_').map {|w| w.capitalize}.join
|
24
|
+
end
|
25
|
+
def to_class
|
26
|
+
Object.const_get self.constantize.singularize
|
27
|
+
end
|
28
|
+
def underscore
|
29
|
+
self.gsub(/::/, '/').
|
30
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
31
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
32
|
+
tr("-", "_").
|
33
|
+
downcase
|
34
|
+
end
|
11
35
|
end
|
data/lib/csv_record/reader.rb
CHANGED
@@ -7,12 +7,12 @@ module CsvRecord
|
|
7
7
|
inst = new
|
8
8
|
params.each do |key, value|
|
9
9
|
inst.public_send("#{key}=", value)
|
10
|
-
end
|
10
|
+
end if params
|
11
11
|
inst
|
12
12
|
end
|
13
13
|
|
14
14
|
def __fields__
|
15
|
-
|
15
|
+
@relevant_instance_variables
|
16
16
|
end
|
17
17
|
|
18
18
|
def all
|
@@ -35,9 +35,8 @@ module CsvRecord
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def __find__(
|
39
|
-
|
40
|
-
(__where__ id: param).first
|
38
|
+
def __find__(condition)
|
39
|
+
(__where__ id: condition.to_param).first
|
41
40
|
end
|
42
41
|
|
43
42
|
def __where__(params)
|
@@ -102,8 +101,13 @@ module CsvRecord
|
|
102
101
|
Hash[self.class.fields.zip self.values]
|
103
102
|
end
|
104
103
|
|
104
|
+
def __to_param__
|
105
|
+
self.id
|
106
|
+
end
|
107
|
+
|
105
108
|
alias :attributes :__attributes__
|
106
109
|
alias :values :__values__
|
110
|
+
alias :to_param :__to_param__
|
107
111
|
end
|
108
112
|
end
|
109
113
|
end
|
data/lib/csv_record/version.rb
CHANGED
data/lib/csv_record/writer.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'csv'
|
2
|
-
|
3
1
|
module CsvRecord
|
4
2
|
module Writer
|
5
3
|
module ClassMethods
|
@@ -11,6 +9,14 @@ module CsvRecord
|
|
11
9
|
instance
|
12
10
|
end
|
13
11
|
|
12
|
+
[:attr_accessor, :attr_writer].each do |custom_accessor|
|
13
|
+
define_method custom_accessor do |*args|
|
14
|
+
@relevant_instance_variables ||= []
|
15
|
+
args.each { |arg| @relevant_instance_variables << arg }
|
16
|
+
super *args
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
14
20
|
alias :create :__create__
|
15
21
|
end
|
16
22
|
|
@@ -53,6 +59,9 @@ module CsvRecord
|
|
53
59
|
|
54
60
|
def calculate_id
|
55
61
|
@id = self.class.count + 1
|
62
|
+
# if self.respond_to? :jedi_order_id
|
63
|
+
# p "#{self.class} -> #{@id} -> #{self.jedi_order_id}"
|
64
|
+
# end
|
56
65
|
end
|
57
66
|
|
58
67
|
def append_registry
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
require_relative '../models/jedi'
|
4
|
+
require_relative '../models/jedi_order'
|
5
|
+
|
6
|
+
describe CsvRecord::Associations do
|
7
|
+
describe 'initializing class methods' do
|
8
|
+
it ('responds to belongs_to') { Jedi.must_respond_to :belongs_to }
|
9
|
+
it ('responds to jedi_order') { Jedi.new.must_respond_to :jedi_order }
|
10
|
+
it ('responds to jedi_order=') { Jedi.new.must_respond_to :jedi_order= }
|
11
|
+
it ('responds to jedi_order_id') { Jedi.new.must_respond_to :jedi_order_id }
|
12
|
+
it ('responds to has_many') { JediOrder.must_respond_to :has_many }
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'belongs_to behavior' do
|
16
|
+
it 'checking to param extraction' do
|
17
|
+
jedi_council.save
|
18
|
+
luke.save
|
19
|
+
luke.jedi_order = jedi_council
|
20
|
+
luke.jedi_order_id.wont_be_nil
|
21
|
+
luke.jedi_order_id.must_be_instance_of Fixnum
|
22
|
+
luke.jedi_order_id.must_equal 1
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'has a single jedi order associated' do
|
26
|
+
jedi_council.save
|
27
|
+
luke.jedi_order = jedi_council
|
28
|
+
luke.save.must_equal true
|
29
|
+
first_jedi = Jedi.first
|
30
|
+
first_jedi.jedi_order.wont_be_nil
|
31
|
+
first_jedi.jedi_order_id.must_be_instance_of Fixnum
|
32
|
+
first_jedi.jedi_order.must_be_instance_of JediOrder
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'has_many behavior' do
|
37
|
+
it 'has many jedis associated' do
|
38
|
+
jedi_council.save
|
39
|
+
yoda.jedi_order = jedi_council
|
40
|
+
yoda.save
|
41
|
+
Jedi.create name: 'Qui-Gon Jinn', age: 37, midi_chlorians: '3k', jedi_order: jedi_council
|
42
|
+
luke.save
|
43
|
+
jedis = jedi_council.jedis
|
44
|
+
jedis.count.must_equal 2
|
45
|
+
jedis.first.must_be_instance_of Jedi
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -63,6 +63,13 @@ describe CsvRecord::Reader do
|
|
63
63
|
Car.count.must_equal 2
|
64
64
|
end
|
65
65
|
|
66
|
+
it 'checking to_param' do
|
67
|
+
car.save
|
68
|
+
car.to_param.wont_be_nil
|
69
|
+
car.to_param.must_be_instance_of Fixnum
|
70
|
+
car.to_param.must_equal 1
|
71
|
+
end
|
72
|
+
|
66
73
|
describe 'simple query' do
|
67
74
|
let (:cars) { [] }
|
68
75
|
|
@@ -118,8 +125,8 @@ describe CsvRecord::Reader do
|
|
118
125
|
result = Car.where year: 2008, make: 'Chevroletion'
|
119
126
|
result.must_be_empty
|
120
127
|
end
|
121
|
-
|
122
128
|
end
|
129
|
+
|
123
130
|
describe 'dynamic finders' do
|
124
131
|
before do
|
125
132
|
car.save
|
data/test/models/jedi.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'csv_record'
|
2
|
+
|
3
|
+
class Jedi
|
4
|
+
include CsvRecord::Document
|
5
|
+
|
6
|
+
belongs_to :jedi_order
|
7
|
+
|
8
|
+
def initialize(params={})
|
9
|
+
params.each do |key, value|
|
10
|
+
self.public_send("#{key}=", value)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :name, :age, :midi_chlorians
|
15
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -2,6 +2,8 @@ require 'minitest/spec'
|
|
2
2
|
require 'minitest/autorun'
|
3
3
|
require 'turn'
|
4
4
|
|
5
|
+
require 'csv_record'
|
6
|
+
|
5
7
|
module TestHelper
|
6
8
|
BASE_PATH = File.expand_path("../fixtures", __FILE__)
|
7
9
|
|
@@ -24,4 +26,27 @@ class MiniTest::Spec
|
|
24
26
|
price: 3000.00
|
25
27
|
)
|
26
28
|
end
|
29
|
+
|
30
|
+
let(:jedi_council) { JediOrder.build rank: 'council' }
|
31
|
+
let(:luke) do
|
32
|
+
Jedi.build(
|
33
|
+
name: 'Luke Skywalker',
|
34
|
+
age: 18,
|
35
|
+
midi_chlorians: '12k'
|
36
|
+
)
|
37
|
+
end
|
38
|
+
let(:yoda) do
|
39
|
+
Jedi.build(
|
40
|
+
name: 'Yoda the green',
|
41
|
+
age: 852,
|
42
|
+
midi_chlorians: '8k'
|
43
|
+
)
|
44
|
+
end
|
45
|
+
let(:qui_gon_jinn) do
|
46
|
+
Jedi.build(
|
47
|
+
name: 'Qui-Gon Jinn',
|
48
|
+
age: 37,
|
49
|
+
midi_chlorians: '3k'
|
50
|
+
)
|
51
|
+
end
|
27
52
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csv_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: rake
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -74,6 +90,7 @@ files:
|
|
74
90
|
- Rakefile
|
75
91
|
- csv_record.gemspec
|
76
92
|
- lib/csv_record.rb
|
93
|
+
- lib/csv_record/associations.rb
|
77
94
|
- lib/csv_record/callbacks.rb
|
78
95
|
- lib/csv_record/connector.rb
|
79
96
|
- lib/csv_record/document.rb
|
@@ -82,6 +99,7 @@ files:
|
|
82
99
|
- lib/csv_record/timestamps.rb
|
83
100
|
- lib/csv_record/version.rb
|
84
101
|
- lib/csv_record/writer.rb
|
102
|
+
- test/csv_record/associations_test.rb
|
85
103
|
- test/csv_record/callbacks_test.rb
|
86
104
|
- test/csv_record/connector_test.rb
|
87
105
|
- test/csv_record/csv_record_test.rb
|
@@ -92,6 +110,8 @@ files:
|
|
92
110
|
- test/csv_record/writer_test.rb
|
93
111
|
- test/models/callback_test_class.rb
|
94
112
|
- test/models/car.rb
|
113
|
+
- test/models/jedi.rb
|
114
|
+
- test/models/jedi_order.rb
|
95
115
|
- test/test_helper.rb
|
96
116
|
homepage: https://github.com/lukasalexandre/csv_record
|
97
117
|
licenses: []
|
@@ -119,6 +139,7 @@ specification_version: 3
|
|
119
139
|
summary: CSV Record connects Ruby classes to CSV documents database to establish an
|
120
140
|
almost zero-configuration persistence layer for applications.
|
121
141
|
test_files:
|
142
|
+
- test/csv_record/associations_test.rb
|
122
143
|
- test/csv_record/callbacks_test.rb
|
123
144
|
- test/csv_record/connector_test.rb
|
124
145
|
- test/csv_record/csv_record_test.rb
|
@@ -129,4 +150,6 @@ test_files:
|
|
129
150
|
- test/csv_record/writer_test.rb
|
130
151
|
- test/models/callback_test_class.rb
|
131
152
|
- test/models/car.rb
|
153
|
+
- test/models/jedi.rb
|
154
|
+
- test/models/jedi_order.rb
|
132
155
|
- test/test_helper.rb
|