ephemeral 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.0
1
+ 1.2.0
data/ephemeral.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "ephemeral"
8
- s.version = "1.1.0"
8
+ s.version = "1.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Corey Ehmke"]
12
- s.date = "2012-09-11"
12
+ s.date = "2012-09-24"
13
13
  s.description = "Ephemeral lets you define one-to-many relationships between in-memory objects, with ORM-like support for where clauses and chainable scopes."
14
14
  s.email = "corey@idolhands.com"
15
15
  s.extra_rdoc_files = [
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
27
27
  "lib/ephemeral.rb",
28
28
  "lib/ephemeral/base.rb",
29
29
  "lib/ephemeral/collection.rb",
30
+ "lib/ephemeral/relation.rb",
30
31
  "spec/ephemeral_spec.rb"
31
32
  ]
32
33
  s.homepage = "http://github.com/Bantik/ephemeral"
@@ -7,7 +7,7 @@ module Ephemeral
7
7
 
8
8
  def self.included(base)
9
9
  base.extend ClassMethods
10
- base.send(:attr_accessor, :collections)
10
+ base.send(:attr_accessor, :collections, :relations)
11
11
  end
12
12
 
13
13
  module ClassMethods
@@ -24,6 +24,18 @@ module Ephemeral
24
24
  end
25
25
  end
26
26
 
27
+ def has_one(name, args={})
28
+ class_name = args[:class_name] || name.to_s.classify
29
+ self.send :define_method, name do
30
+ self.relations ||= {}
31
+ self.relations[class_name] ||= Ephemeral::Relation.new(class_name).materialize
32
+ end
33
+ self.send :define_method, "#{name}=" do |object|
34
+ self.relations ||= {}
35
+ self.relations[class_name] = Ephemeral::Relation.new(class_name).materialize(object)
36
+ end
37
+ end
38
+
27
39
  def scope(name, conditions)
28
40
  self.scopes ||= {}
29
41
  self.scopes[name] = conditions
@@ -23,8 +23,8 @@ module Ephemeral
23
23
 
24
24
  def where(args={})
25
25
  return [] unless self.objects
26
- results = args.inject([]){|a,kv| a << self.objects.select{|o| o.send(kv[0]) == kv[1]}}
27
- results = results.flatten.select{|r| results.flatten.count(r) == results.count}.uniq
26
+ results = args.inject([]) {|a, (k, v)| a << self.objects.select {|o| o.send(k) == v} }
27
+ results = results.flatten.select {|r| results.flatten.count(r) == results.count }.uniq
28
28
  end
29
29
 
30
30
  def last
@@ -39,8 +39,8 @@ module Ephemeral
39
39
 
40
40
  def execute_scope(method)
41
41
  return Ephemeral::Collection.new(self.klass.name) unless self.objects
42
- results = self.klass.scopes[method].inject([]){|a,kv| a << self.objects.select{|o| o.send(kv[0]) == kv[1]}}
43
- results = results.flatten.select{|r| results.flatten.count(r) == results.count}.uniq
42
+ results = self.klass.scopes[method].inject([]) {|a, (k, v)| a << self.objects.select {|o| o.send(k) == v } }
43
+ results = results.flatten.select {|r| results.flatten.count(r) == results.count }.uniq
44
44
  Ephemeral::Collection.new(self.klass.name, results)
45
45
  end
46
46
 
@@ -0,0 +1,21 @@
1
+ module Ephemeral
2
+
3
+ class Relation
4
+
5
+ attr_accessor :object, :klass
6
+
7
+ def initialize(klass, object=nil)
8
+ self.klass = eval(klass)
9
+ self.object = self.materialize(object)
10
+ self
11
+ end
12
+
13
+ def materialize(object=nil)
14
+ return nil unless object
15
+ return object if object.is_a? self.klass
16
+ self.klass.new(object)
17
+ end
18
+
19
+ end
20
+
21
+ end
data/lib/ephemeral.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  module Ephemeral
2
2
  require 'ephemeral/base'
3
3
  require 'ephemeral/collection'
4
+ require 'ephemeral/relation'
4
5
  end
@@ -11,6 +11,7 @@ end
11
11
 
12
12
  class Antique
13
13
  include Ephemeral::Base
14
+ has_one :picker
14
15
  attr_accessor :name, :item_count
15
16
  def initialize(args={}); args.each{|k,v| self.send("#{k}=", v)}; end
16
17
  end
@@ -21,6 +22,12 @@ class NotCollectible
21
22
  def initialize(args={}); args.each{|k,v| self.send("#{k}=", v)}; end
22
23
  end
23
24
 
25
+ class Picker
26
+ include Ephemeral::Base
27
+ attr_accessor :name
28
+ def initialize(args={}); args.each{|k,v| self.send("#{k}=", v)}; end
29
+ end
30
+
24
31
  class Collector
25
32
  include Ephemeral::Base
26
33
  attr_accessor :name
@@ -34,81 +41,108 @@ describe Ephemeral do
34
41
 
35
42
  context 'class methods' do
36
43
 
37
- it 'defines a collection' do
38
- Collector.new.rarities.klass.should == Rarity
39
- Collector.new.antiques.klass.should == Antique
40
- end
44
+ context 'collections' do
41
45
 
42
- it 'accepts a class name' do
43
- Collector.new.junk.klass.should == NotCollectible
44
- end
46
+ it 'defines a collection' do
47
+ Collector.new.rarities.klass.should == Rarity
48
+ Collector.new.antiques.klass.should == Antique
49
+ end
45
50
 
46
- it 'creates a setter' do
47
- Collector.new.respond_to?(:rarities=).should be_true
48
- end
51
+ it 'accepts a class name' do
52
+ Collector.new.junk.klass.should == NotCollectible
53
+ end
49
54
 
50
- it 'creates a getter' do
51
- Collector.new.respond_to?(:rarities).should be_true
52
- end
55
+ it 'creates a setter' do
56
+ Collector.new.respond_to?(:rarities=).should be_true
57
+ end
58
+
59
+ it 'creates a getter' do
60
+ Collector.new.respond_to?(:rarities).should be_true
61
+ end
62
+
63
+ it 'registers a scope' do
64
+ Rarity.scopes.include?(:foos).should be_true
65
+ end
53
66
 
54
- it 'registers a scope' do
55
- Rarity.scopes.include?(:foos).should be_true
56
67
  end
57
68
 
69
+ context 'relations' do
70
+
71
+ it 'defines a relation' do
72
+ Antique.new(:picker => {:name => 'Frank Fritz'}).picker.is_a?(Picker).should be_true
73
+ end
74
+
75
+ end
58
76
  end
59
77
 
60
78
  context 'instance methods' do
61
79
 
62
- before :each do
63
-
64
- @rarities = [
65
- Rarity.new(:name => 'Paychecks', :item_count => 1),
66
- Rarity.new(:name => 'Paychecks', :item_count => 3),
67
- Rarity.new(:name => 'Requisitions', :item_count => 2),
68
- ]
80
+ context 'relations' do
69
81
 
70
- @antiques = [
71
- Antique.new(:name => 'Trading Cards', :item_count => 100)
72
- ]
82
+ before :each do
83
+ @antique = Antique.new(:name => 'Model T Ford', :item_count => 1, :picker => {:name => "Mike Wolfe"} )
84
+ end
73
85
 
74
- @collector = Collector.new(:name => 'Hermes')
75
- @collector.rarities = @rarities
76
- @collector.antiques = @antiques
86
+ it 'initializes with a materialized object' do
87
+ @antique.picker.name.should == "Mike Wolfe"
88
+ end
77
89
 
78
90
  end
79
91
 
80
- describe 'initializes with materialized objects' do
81
-
82
- it 'from a setter' do
83
- collector = Collector.new(
84
- :name => 'from_api',
85
- 'rarities' => [
86
- {'name' => 'foo'},
87
- {'name' => 'bar'}
88
- ]
89
- )
90
- collector.rarities.count.should == 2
91
- end
92
+ context 'collections' do
92
93
 
93
- end
94
+ before :each do
94
95
 
95
- it 'performs a where' do
96
- @collector.rarities.where(:name => 'Paychecks').should_not be_blank
97
- @collector.antiques.where(:name => 'Trading Cards').should_not be_blank
98
- end
96
+ @rarities = [
97
+ Rarity.new(:name => 'Paychecks', :item_count => 1),
98
+ Rarity.new(:name => 'Paychecks', :item_count => 3),
99
+ Rarity.new(:name => 'Requisitions', :item_count => 2),
100
+ ]
101
+
102
+ @antiques = [
103
+ Antique.new(:name => 'Trading Cards', :item_count => 100)
104
+ ]
99
105
 
100
- describe 'scope method' do
106
+ @collector = Collector.new(:name => 'Hermes')
107
+ @collector.rarities = @rarities
108
+ @collector.antiques = @antiques
101
109
 
102
- it 'executes a scope' do
103
- @collector.rarities.paychecks.first.should_not be_nil
104
110
  end
105
111
 
106
- it 'returns a collection' do
107
- @collector.rarities.paychecks.class.name.should == 'Ephemeral::Collection'
112
+ describe 'initializes with materialized objects' do
113
+
114
+ it 'from a setter' do
115
+ collector = Collector.new(
116
+ :name => 'from_api',
117
+ 'rarities' => [
118
+ {'name' => 'foo'},
119
+ {'name' => 'bar'}
120
+ ]
121
+ )
122
+ collector.rarities.count.should == 2
123
+ end
124
+
125
+ end
126
+
127
+ it 'performs a where' do
128
+ @collector.rarities.where(:name => 'Paychecks').should_not be_blank
129
+ @collector.antiques.where(:name => 'Trading Cards').should_not be_blank
108
130
  end
109
131
 
110
- it 'chains scopes' do
111
- @collector.rarities.paychecks.threes.count.should == 1
132
+ describe 'scope method' do
133
+
134
+ it 'executes a scope' do
135
+ @collector.rarities.paychecks.first.should_not be_nil
136
+ end
137
+
138
+ it 'returns a collection' do
139
+ @collector.rarities.paychecks.class.name.should == 'Ephemeral::Collection'
140
+ end
141
+
142
+ it 'chains scopes' do
143
+ @collector.rarities.paychecks.threes.count.should == 1
144
+ end
145
+
112
146
  end
113
147
 
114
148
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ephemeral
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.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-11 00:00:00.000000000 Z
12
+ date: 2012-09-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -110,6 +110,7 @@ files:
110
110
  - lib/ephemeral.rb
111
111
  - lib/ephemeral/base.rb
112
112
  - lib/ephemeral/collection.rb
113
+ - lib/ephemeral/relation.rb
113
114
  - spec/ephemeral_spec.rb
114
115
  homepage: http://github.com/Bantik/ephemeral
115
116
  licenses:
@@ -126,7 +127,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
126
127
  version: '0'
127
128
  segments:
128
129
  - 0
129
- hash: 4564368402779681866
130
+ hash: -1586023366873335519
130
131
  required_rubygems_version: !ruby/object:Gem::Requirement
131
132
  none: false
132
133
  requirements: