ephemeral 1.1.0 → 1.2.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/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: