hystorical 0.2.0 → 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
CHANGED
@@ -99,11 +99,17 @@ $ rails g hystorical:dates Subscription
|
|
99
99
|
$ create db/migrate/20120917150948_add_start_date_end_date_to_subscriptions.rb
|
100
100
|
```
|
101
101
|
|
102
|
+
## Filtering
|
103
|
+
|
104
|
+
You can filter a dataset by passing in a block. This works similarly to Enumerable's `select` method.
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
Hystorical.current subscriptions { |subscription| subscription.type == :gold }
|
108
|
+
```
|
109
|
+
|
102
110
|
## Philosophy
|
103
111
|
This gem was created using TDD and README-driven development. The architecture was designed with a strong focus on modularity and extensibility. Using ruby's `Enumerable` methods to return current object was chosen because of it's great flexibility to adapt to all ruby projects. However, when working with large datasets stored in a relational database, using SQL would yield greater performance. An adapter was added for ActiveRecord, but extending this to another ORM (such as DataMapper or Mongoid) is as simple as creating a new class that defines all the methods in the public api and adding a conditional in `Hystorical.delegate_class`.
|
104
112
|
|
105
|
-
## TODO
|
106
|
-
* Add ability to pass in a block option that can further filter results
|
107
113
|
|
108
114
|
## Contributing
|
109
115
|
|
@@ -2,11 +2,13 @@ module Hystorical
|
|
2
2
|
class ARRelation
|
3
3
|
class << self
|
4
4
|
def current(collection)
|
5
|
-
collection.where(end_date: nil)
|
5
|
+
current_items = collection.where(end_date: nil)
|
6
|
+
block_given? ? current_items.select { |item| yield item } : current_items
|
6
7
|
end
|
7
8
|
|
8
9
|
def current_on(collection, date)
|
9
|
-
collection.where("? BETWEEN start_date AND end_date", date)
|
10
|
+
current_items = collection.where("? BETWEEN start_date AND end_date", date)
|
11
|
+
block_given? ? current_items.select { |item| yield item } : current_items
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
@@ -3,18 +3,24 @@ module Hystorical
|
|
3
3
|
class << self
|
4
4
|
|
5
5
|
def current(collection)
|
6
|
-
collection.select
|
6
|
+
collection.select do |obj|
|
7
|
+
current = get_attr(obj, :end_date).nil?
|
8
|
+
block_given? ? (yield obj) && current : current
|
9
|
+
end
|
7
10
|
end
|
8
11
|
|
9
12
|
def current_on(collection, date)
|
10
13
|
collection.select do |obj|
|
11
|
-
|
12
|
-
|
13
|
-
else
|
14
|
-
obj.start_date <= date && obj.end_date >= date
|
15
|
-
end
|
14
|
+
current = (get_attr(obj, :start_date) <= date) && (get_attr(obj, :end_date) >= date)
|
15
|
+
block_given? ? (yield obj) && current : current
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def get_attr(obj, attribute)
|
21
|
+
obj.respond_to?(:[]) ? obj[attribute] : obj.send(attribute)
|
22
|
+
end
|
23
|
+
|
18
24
|
end
|
19
25
|
end
|
20
26
|
end
|
data/lib/hystorical/version.rb
CHANGED
@@ -5,6 +5,7 @@ describe Hystorical::ARRelation do
|
|
5
5
|
with_model :Subscription do
|
6
6
|
table do |t|
|
7
7
|
t.integer :user_id
|
8
|
+
t.string :service
|
8
9
|
t.date :start_date
|
9
10
|
t.date :end_date
|
10
11
|
end
|
@@ -17,16 +18,25 @@ describe Hystorical::ARRelation do
|
|
17
18
|
end
|
18
19
|
|
19
20
|
describe "current" do
|
20
|
-
let!(:obj1) { Subscription.create(user_id: 1, start_date: Date.new(2012, 9, 1), end_date: nil) }
|
21
|
-
let!(:obj2) { Subscription.create(user_id: 2, start_date: Date.new(2012, 9, 6), end_date: Date.new(2012, 9, 10)) }
|
22
|
-
let!(:obj3) { Subscription.create(user_id: 2, start_date: Date.new(2012, 9, 11), end_date: nil) }
|
21
|
+
let!(:obj1) { Subscription.create(user_id: 1, service: "gold", start_date: Date.new(2012, 9, 1), end_date: nil) }
|
22
|
+
let!(:obj2) { Subscription.create(user_id: 2, service: "silver", start_date: Date.new(2012, 9, 6), end_date: Date.new(2012, 9, 10)) }
|
23
|
+
let!(:obj3) { Subscription.create(user_id: 2, service: "gold", start_date: Date.new(2012, 9, 11), end_date: nil) }
|
23
24
|
|
24
25
|
it "should return the current subscription" do
|
25
26
|
Hystorical::ARRelation.current(Subscription.for_user(2)).should eq [obj3]
|
26
27
|
end
|
28
|
+
|
29
|
+
context "block filter" do
|
30
|
+
let!(:obj4) { Subscription.create(user_id: 2, service: "silver", start_date: Date.new(2012, 9, 6), end_date: nil) }
|
31
|
+
it "should return the current filtered subscriptions" do
|
32
|
+
Hystorical::ARRelation.current Subscription.for_user(2) do |sub|
|
33
|
+
sub.service == "silver"
|
34
|
+
end.should eq [obj4]
|
35
|
+
end
|
36
|
+
end
|
27
37
|
end
|
28
38
|
|
29
|
-
describe "
|
39
|
+
describe "current_on" do
|
30
40
|
let!(:obj1) { Subscription.create(user_id: 1, start_date: Date.new(2012, 9, 1), end_date: nil) }
|
31
41
|
let!(:obj2) { Subscription.create(user_id: 2, start_date: Date.new(2012, 9, 6), end_date: Date.new(2012, 9, 10)) }
|
32
42
|
let!(:obj3) { Subscription.create(user_id: 2, start_date: Date.new(2012, 9, 11), end_date: nil) }
|
@@ -34,5 +44,14 @@ describe Hystorical::ARRelation do
|
|
34
44
|
it "should return the current subscription as of Sept 8" do
|
35
45
|
Hystorical::ARRelation.current_on(Subscription.for_user(2), Date.new(2012, 9, 8)).should eq [obj2]
|
36
46
|
end
|
47
|
+
|
48
|
+
context "block filter" do
|
49
|
+
let!(:obj4) { Subscription.create(user_id: 2, service: "gold", start_date: Date.new(2012, 9, 6), end_date: Date.new(2012, 9, 10)) }
|
50
|
+
it "should return the current filtered subscriptions" do
|
51
|
+
Hystorical::ARRelation.current_on Subscription.for_user(2), Date.new(2012, 9, 8) do |sub|
|
52
|
+
sub.service == "gold"
|
53
|
+
end.should eq [obj4]
|
54
|
+
end
|
55
|
+
end
|
37
56
|
end
|
38
57
|
end
|
@@ -2,23 +2,24 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Hystorical::RubyCollection do
|
4
4
|
class HistoricalObjet
|
5
|
-
attr_accessor :start_date, :end_date
|
5
|
+
attr_accessor :start_date, :end_date, :type
|
6
6
|
|
7
|
-
def initialize(start_date, end_date)
|
7
|
+
def initialize(type, start_date, end_date)
|
8
|
+
@type = type
|
8
9
|
@start_date = start_date
|
9
10
|
@end_date = end_date
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
13
|
-
let(:obj1) { {start_date: Date.new(2012, 8, 15), end_date: Date.new(2012, 8, 26)} }
|
14
|
-
let(:obj2) { {start_date: Date.new(2012, 8, 27), end_date: Date.new(2012, 9, 4)} }
|
15
|
-
let(:obj3) { {start_date: Date.new(2012, 9, 5), end_date: nil} }
|
14
|
+
let(:obj1) { {type: :gold, start_date: Date.new(2012, 8, 15), end_date: Date.new(2012, 8, 26)} }
|
15
|
+
let(:obj2) { {type: :silver, start_date: Date.new(2012, 8, 27), end_date: Date.new(2012, 9, 4)} }
|
16
|
+
let(:obj3) { {type: :gold, start_date: Date.new(2012, 9, 5), end_date: nil} }
|
16
17
|
let(:collection) { [obj1, obj2, obj3] }
|
17
18
|
|
18
19
|
|
19
|
-
let(:obj4) { HistoricalObjet.new(Date.new(2012, 8, 15), Date.new(2012, 8, 26)) }
|
20
|
-
let(:obj5) { HistoricalObjet.new(Date.new(2012, 8, 27), Date.new(2012, 9, 4)) }
|
21
|
-
let(:obj6) { HistoricalObjet.new(Date.new(2012, 9, 5), nil) }
|
20
|
+
let(:obj4) { HistoricalObjet.new(:gold, Date.new(2012, 8, 15), Date.new(2012, 8, 26)) }
|
21
|
+
let(:obj5) { HistoricalObjet.new(:silver, Date.new(2012, 8, 27), Date.new(2012, 9, 4)) }
|
22
|
+
let(:obj6) { HistoricalObjet.new(:gold, Date.new(2012, 9, 5), nil) }
|
22
23
|
let(:collection2) { [obj4, obj5, obj6] }
|
23
24
|
|
24
25
|
describe ".current" do
|
@@ -33,6 +34,15 @@ describe Hystorical::RubyCollection do
|
|
33
34
|
Hystorical::RubyCollection.current(collection2).should eq [obj6]
|
34
35
|
end
|
35
36
|
end
|
37
|
+
|
38
|
+
context "filter block" do
|
39
|
+
let(:obj5) { HistoricalObjet.new(:silver, Date.new(2012, 8, 27), nil) }
|
40
|
+
it "should be filterable via a block" do
|
41
|
+
Hystorical::RubyCollection.current collection2 do |sub|
|
42
|
+
sub.type == :silver
|
43
|
+
end.should eq [obj5]
|
44
|
+
end
|
45
|
+
end
|
36
46
|
end
|
37
47
|
|
38
48
|
describe ".current_on" do
|
@@ -49,5 +59,14 @@ describe Hystorical::RubyCollection do
|
|
49
59
|
Hystorical::RubyCollection.current_on(collection2, date).should eq [obj5]
|
50
60
|
end
|
51
61
|
end
|
62
|
+
|
63
|
+
context "filter block" do
|
64
|
+
let(:obj6) { HistoricalObjet.new(:gold, Date.new(2012, 9, 5), Date.new(2012, 9, 4)) }
|
65
|
+
it "should be filterable via a block" do
|
66
|
+
Hystorical::RubyCollection.current_on collection2, date do |sub|
|
67
|
+
sub.type == :silver
|
68
|
+
end.should eq [obj5]
|
69
|
+
end
|
70
|
+
end
|
52
71
|
end
|
53
72
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hystorical
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-09-
|
12
|
+
date: 2012-09-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|