joiner 0.1.0 → 0.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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/joiner.gemspec +1 -1
- data/lib/joiner.rb +2 -1
- data/lib/joiner/path.rb +5 -1
- data/spec/acceptance/paths_spec.rb +2 -2
- data/spec/joiner/joins_spec.rb +179 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b7b02b7622a82eeefbf7a3abca876d752e809d0
|
4
|
+
data.tar.gz: 9b6809d20db5b15abb97f40a06349a8186d3f863
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33aac1b4d121b51ed4a23f314478135f0514e583c880c06c4b8931ef1e0fb07211ee142813e13e6d230a94096dfa486c31f60fe48bcd22df6583c8d96d29177c
|
7
|
+
data.tar.gz: 8ca6904f2f5e37fbf49eeee879af83e261a650fae726a1263a46a3013105de0a1da8ccfe2665cac1cfe22ab9d227cc520319f8d965ad98ae416e0b8ce8f670a8
|
data/README.md
CHANGED
@@ -9,7 +9,7 @@ If this gem is used by anyone other than myself/Thinking Sphinx, I'll be surpris
|
|
9
9
|
It's a gem - so you can either install it yourself, or add it to the appropriate Gemfile or gemspec.
|
10
10
|
|
11
11
|
```term
|
12
|
-
gem install joiner --version 0.
|
12
|
+
gem install joiner --version 0.2.0
|
13
13
|
```
|
14
14
|
|
15
15
|
## Usage
|
data/joiner.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
Gem::Specification.new do |spec|
|
3
3
|
spec.name = 'joiner'
|
4
|
-
spec.version = '0.
|
4
|
+
spec.version = '0.2.0'
|
5
5
|
spec.authors = ['Pat Allan']
|
6
6
|
spec.email = ['pat@freelancing-gods.com']
|
7
7
|
spec.summary = %q{Builds ActiveRecord joins from association paths}
|
data/lib/joiner.rb
CHANGED
data/lib/joiner/path.rb
CHANGED
@@ -25,7 +25,11 @@ class Joiner::Path
|
|
25
25
|
klass = base
|
26
26
|
path.collect { |reference|
|
27
27
|
klass.reflect_on_association(reference).tap { |reflection|
|
28
|
-
|
28
|
+
if reflection.nil?
|
29
|
+
raise Joiner::AssociationNotFound,
|
30
|
+
"No association matching #{base.name}, #{path.join(', ')}"
|
31
|
+
end
|
32
|
+
|
29
33
|
klass = reflection.klass
|
30
34
|
}
|
31
35
|
}
|
@@ -34,10 +34,10 @@ describe 'Paths' do
|
|
34
34
|
expect(path.model).to eq(User)
|
35
35
|
end
|
36
36
|
|
37
|
-
it "
|
37
|
+
it "raises an exception if the path is invalid" do
|
38
38
|
path = Joiner::Path.new User, [:articles, :likes]
|
39
39
|
|
40
|
-
expect
|
40
|
+
expect { path.model }.to raise_error(Joiner::AssociationNotFound)
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Joiner::Joins do
|
4
|
+
JoinDependency = ::ActiveRecord::Associations::JoinDependency
|
5
|
+
|
6
|
+
let(:joins) { Joiner::Joins.new model }
|
7
|
+
let(:model) { model_double 'articles' }
|
8
|
+
let(:base) {
|
9
|
+
double('base', :active_record => model, :join_base => join_base)
|
10
|
+
}
|
11
|
+
let(:join_base) { double('join base') }
|
12
|
+
let(:join) { join_double 'users' }
|
13
|
+
let(:sub_join) { join_double 'posts' }
|
14
|
+
|
15
|
+
def join_double(table_alias)
|
16
|
+
double 'join',
|
17
|
+
:join_type= => nil,
|
18
|
+
:aliased_table_name => table_alias,
|
19
|
+
:reflection => double('reflection'),
|
20
|
+
:conditions => []
|
21
|
+
end
|
22
|
+
|
23
|
+
def model_double(table_name = nil)
|
24
|
+
double 'model', :quoted_table_name => table_name, :reflections => {}
|
25
|
+
end
|
26
|
+
|
27
|
+
before :each do
|
28
|
+
JoinDependency.stub :new => base
|
29
|
+
JoinDependency::JoinAssociation.stub(:new).and_return(join, sub_join)
|
30
|
+
model.reflections[:user] = join.reflection
|
31
|
+
|
32
|
+
join.stub :active_record => model_double
|
33
|
+
join.active_record.reflections[:posts] = sub_join.reflection
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#add_join_to' do
|
37
|
+
before :each do
|
38
|
+
JoinDependency::JoinAssociation.unstub :new
|
39
|
+
end
|
40
|
+
|
41
|
+
it "adds just one join for a stack with a single association" do
|
42
|
+
JoinDependency::JoinAssociation.should_receive(:new).
|
43
|
+
with(join.reflection, base, join_base).once.and_return(join)
|
44
|
+
|
45
|
+
joins.add_join_to([:user])
|
46
|
+
end
|
47
|
+
|
48
|
+
it "does not duplicate joins when given the same stack twice" do
|
49
|
+
JoinDependency::JoinAssociation.should_receive(:new).once.and_return(join)
|
50
|
+
|
51
|
+
joins.add_join_to([:user])
|
52
|
+
joins.add_join_to([:user])
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'multiple joins' do
|
56
|
+
it "adds two joins for a stack with two associations" do
|
57
|
+
JoinDependency::JoinAssociation.should_receive(:new).
|
58
|
+
with(join.reflection, base, join_base).once.and_return(join)
|
59
|
+
JoinDependency::JoinAssociation.should_receive(:new).
|
60
|
+
with(sub_join.reflection, base, join).once.and_return(sub_join)
|
61
|
+
|
62
|
+
joins.add_join_to([:user, :posts])
|
63
|
+
end
|
64
|
+
|
65
|
+
it "extends upon existing joins when given stacks where parts are already mapped" do
|
66
|
+
JoinDependency::JoinAssociation.should_receive(:new).twice.
|
67
|
+
and_return(join, sub_join)
|
68
|
+
|
69
|
+
joins.add_join_to([:user])
|
70
|
+
joins.add_join_to([:user, :posts])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'join with conditions' do
|
75
|
+
let(:connection) { double }
|
76
|
+
let(:parent) { double :aliased_table_name => 'qux' }
|
77
|
+
|
78
|
+
before :each do
|
79
|
+
JoinDependency::JoinAssociation.stub :new => join
|
80
|
+
|
81
|
+
join.stub :parent => parent
|
82
|
+
model.stub :connection => connection
|
83
|
+
connection.stub(:quote_table_name) { |table| "\"#{table}\"" }
|
84
|
+
end
|
85
|
+
|
86
|
+
it "leaves standard conditions untouched" do
|
87
|
+
join.stub :conditions => 'foo = bar'
|
88
|
+
|
89
|
+
joins.add_join_to [:user]
|
90
|
+
|
91
|
+
join.conditions.should == 'foo = bar'
|
92
|
+
end
|
93
|
+
|
94
|
+
it "modifies filtered polymorphic conditions" do
|
95
|
+
join.stub :conditions => '::ts_join_alias::.foo = bar'
|
96
|
+
|
97
|
+
joins.add_join_to [:user]
|
98
|
+
|
99
|
+
join.conditions.should == '"qux".foo = bar'
|
100
|
+
end
|
101
|
+
|
102
|
+
it "modifies filtered polymorphic conditions within arrays" do
|
103
|
+
join.stub :conditions => ['::ts_join_alias::.foo = bar']
|
104
|
+
|
105
|
+
joins.add_join_to [:user]
|
106
|
+
|
107
|
+
join.conditions.should == ['"qux".foo = bar']
|
108
|
+
end
|
109
|
+
|
110
|
+
it "does not modify conditions as hashes" do
|
111
|
+
join.stub :conditions => [{:foo => 'bar'}]
|
112
|
+
|
113
|
+
joins.add_join_to [:user]
|
114
|
+
|
115
|
+
join.conditions.should == [{:foo => 'bar'}]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#alias_for' do
|
121
|
+
it "returns the model's table name when no stack is given" do
|
122
|
+
joins.alias_for([]).should == 'articles'
|
123
|
+
end
|
124
|
+
|
125
|
+
it "adds just one join for a stack with a single association" do
|
126
|
+
JoinDependency::JoinAssociation.unstub :new
|
127
|
+
JoinDependency::JoinAssociation.should_receive(:new).
|
128
|
+
with(join.reflection, base, join_base).once.and_return(join)
|
129
|
+
|
130
|
+
joins.alias_for([:user])
|
131
|
+
end
|
132
|
+
|
133
|
+
it "returns the aliased table name for the join" do
|
134
|
+
joins.alias_for([:user]).should == 'users'
|
135
|
+
end
|
136
|
+
|
137
|
+
it "does not duplicate joins when given the same stack twice" do
|
138
|
+
JoinDependency::JoinAssociation.unstub :new
|
139
|
+
JoinDependency::JoinAssociation.should_receive(:new).once.and_return(join)
|
140
|
+
|
141
|
+
joins.alias_for([:user])
|
142
|
+
joins.alias_for([:user])
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'multiple joins' do
|
146
|
+
it "adds two joins for a stack with two associations" do
|
147
|
+
JoinDependency::JoinAssociation.unstub :new
|
148
|
+
JoinDependency::JoinAssociation.should_receive(:new).
|
149
|
+
with(join.reflection, base, join_base).once.and_return(join)
|
150
|
+
JoinDependency::JoinAssociation.should_receive(:new).
|
151
|
+
with(sub_join.reflection, base, join).once.and_return(sub_join)
|
152
|
+
|
153
|
+
joins.alias_for([:user, :posts])
|
154
|
+
end
|
155
|
+
|
156
|
+
it "returns the sub join's aliased table name" do
|
157
|
+
joins.alias_for([:user, :posts]).should == 'posts'
|
158
|
+
end
|
159
|
+
|
160
|
+
it "extends upon existing joins when given stacks where parts are already mapped" do
|
161
|
+
JoinDependency::JoinAssociation.unstub :new
|
162
|
+
JoinDependency::JoinAssociation.should_receive(:new).twice.
|
163
|
+
and_return(join, sub_join)
|
164
|
+
|
165
|
+
joins.alias_for([:user])
|
166
|
+
joins.alias_for([:user, :posts])
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe '#join_values' do
|
172
|
+
it "returns all joins that have been created" do
|
173
|
+
joins.alias_for([:user])
|
174
|
+
joins.alias_for([:user, :posts])
|
175
|
+
|
176
|
+
joins.join_values.should == [join, sub_join]
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: joiner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pat Allan
|
@@ -97,6 +97,7 @@ files:
|
|
97
97
|
- spec/internal/config/database.yml
|
98
98
|
- spec/internal/db/schema.rb
|
99
99
|
- spec/internal/log/.gitignore
|
100
|
+
- spec/joiner/joins_spec.rb
|
100
101
|
- spec/spec_helper.rb
|
101
102
|
homepage: https://github.com/pat/joiner
|
102
103
|
licenses:
|
@@ -131,4 +132,5 @@ test_files:
|
|
131
132
|
- spec/internal/config/database.yml
|
132
133
|
- spec/internal/db/schema.rb
|
133
134
|
- spec/internal/log/.gitignore
|
135
|
+
- spec/joiner/joins_spec.rb
|
134
136
|
- spec/spec_helper.rb
|