surus 0.6.5 → 0.7.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/CHANGELOG.md +4 -0
- data/lib/surus/json.rb +1 -0
- data/lib/surus/json/has_many_through_scope_builder.rb +69 -0
- data/lib/surus/json/query.rb +5 -0
- data/lib/surus/version.rb +1 -1
- data/spec/database_structure.sql +30 -0
- data/spec/factories.rb +15 -0
- data/spec/json/json_spec.rb +54 -0
- data/spec/spec_helper.rb +19 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ba3e32fb91f29014a44a70df352f6863ee8f341
|
4
|
+
data.tar.gz: a7dd13115acd96b38f3369750a05596912a2a90b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fef906f19243ce07000434326b9be81742a4de4ae8f969a526d624ed19b69f36a23834e47d78aad02c296b3f3428411ff20359f998bc6d5d72cef93c2e1a08be
|
7
|
+
data.tar.gz: 886eabfb959223927da81e2ad0dc11977f6b8081861ec1c20211f5955abeb35e74331119b15b745d879c612a8dacf00154f85d04f998a7479e8e5da9854e5e34
|
data/CHANGELOG.md
CHANGED
data/lib/surus/json.rb
CHANGED
@@ -5,4 +5,5 @@ require 'surus/json/model'
|
|
5
5
|
require 'surus/json/association_scope_builder'
|
6
6
|
require 'surus/json/belongs_to_scope_builder'
|
7
7
|
require 'surus/json/has_many_scope_builder'
|
8
|
+
require 'surus/json/has_many_through_scope_builder'
|
8
9
|
require 'surus/json/has_and_belongs_to_many_scope_builder'
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Surus
|
2
|
+
module JSON
|
3
|
+
class HasManyThroughScopeBuilder < AssociationScopeBuilder
|
4
|
+
def scope
|
5
|
+
s = association
|
6
|
+
.klass
|
7
|
+
.joins(through_table_join)
|
8
|
+
.where("#{through_table}.#{through_foreign_key}=#{outside_table}.#{outside_primary_key}")
|
9
|
+
|
10
|
+
s = s.instance_eval(&association.scope) if association.scope
|
11
|
+
s
|
12
|
+
end
|
13
|
+
|
14
|
+
delegate :through_reflection, to: :association
|
15
|
+
|
16
|
+
def through_table_join
|
17
|
+
if foreign_key == through_association_foreign_key
|
18
|
+
join_through_table_foreign_key_on_association
|
19
|
+
else
|
20
|
+
join_through_table_foreign_key_on_through
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def join_through_table_foreign_key_on_association
|
25
|
+
"JOIN #{through_table} ON #{through_table}.#{through_primary_key}=#{association_table}.#{foreign_key}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def join_through_table_foreign_key_on_through
|
29
|
+
"JOIN #{through_table} ON #{through_table}.#{foreign_key}=#{association_table}.#{association_primary_key}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def outside_table
|
33
|
+
outside_class.quoted_table_name
|
34
|
+
end
|
35
|
+
|
36
|
+
def outside_primary_key
|
37
|
+
quote_column_name outside_class.primary_key
|
38
|
+
end
|
39
|
+
|
40
|
+
def foreign_key
|
41
|
+
quote_column_name association.foreign_key
|
42
|
+
end
|
43
|
+
|
44
|
+
def through_table
|
45
|
+
through_reflection.quoted_table_name
|
46
|
+
end
|
47
|
+
|
48
|
+
def through_primary_key
|
49
|
+
quote_column_name through_reflection.active_record_primary_key
|
50
|
+
end
|
51
|
+
|
52
|
+
def through_foreign_key
|
53
|
+
quote_column_name through_reflection.foreign_key
|
54
|
+
end
|
55
|
+
|
56
|
+
def through_association_foreign_key
|
57
|
+
quote_column_name through_reflection.association_foreign_key
|
58
|
+
end
|
59
|
+
|
60
|
+
def association_table
|
61
|
+
quote_table_name association.klass.table_name
|
62
|
+
end
|
63
|
+
|
64
|
+
def association_primary_key
|
65
|
+
quote_column_name association.association_primary_key
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/surus/json/query.rb
CHANGED
@@ -55,6 +55,8 @@ module Surus
|
|
55
55
|
:belongs_to
|
56
56
|
when ActiveRecord::Reflection::HasManyReflection
|
57
57
|
:has_many
|
58
|
+
when ActiveRecord::Reflection::ThroughReflection
|
59
|
+
:has_many_through
|
58
60
|
when ActiveRecord::Reflection::HasAndBelongsToManyReflection
|
59
61
|
:has_and_belongs_to_many
|
60
62
|
end
|
@@ -73,6 +75,9 @@ module Surus
|
|
73
75
|
when :has_many
|
74
76
|
association_scope = HasManyScopeBuilder.new(original_scope, association).scope
|
75
77
|
ArrayAggQuery.new(association_scope, association_options).to_sql
|
78
|
+
when :has_many_through
|
79
|
+
association_scope = HasManyThroughScopeBuilder.new(original_scope, association).scope
|
80
|
+
ArrayAggQuery.new(association_scope, association_options).to_sql
|
76
81
|
when :has_and_belongs_to_many
|
77
82
|
association_scope = HasAndBelongsToManyScopeBuilder.new(original_scope, association).scope
|
78
83
|
ArrayAggQuery.new(association_scope, association_options).to_sql
|
data/lib/surus/version.rb
CHANGED
data/spec/database_structure.sql
CHANGED
@@ -120,3 +120,33 @@ CREATE TABLE posts_tags(
|
|
120
120
|
tag_id integer NOT NULL REFERENCES tags,
|
121
121
|
PRIMARY KEY (post_id, tag_id)
|
122
122
|
);
|
123
|
+
|
124
|
+
|
125
|
+
|
126
|
+
DROP TABLE IF EXISTS comments CASCADE;
|
127
|
+
|
128
|
+
CREATE TABLE comments(
|
129
|
+
id serial PRIMARY KEY,
|
130
|
+
post_id integer NOT NULL REFERENCES posts,
|
131
|
+
name varchar NOT NULL,
|
132
|
+
body varchar NOT NULL
|
133
|
+
);
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
DROP TABLE IF EXISTS medias CASCADE;
|
138
|
+
|
139
|
+
CREATE TABLE medias(
|
140
|
+
id serial PRIMARY KEY,
|
141
|
+
url varchar NOT NULL
|
142
|
+
);
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
DROP TABLE IF EXISTS post_medias CASCADE;
|
147
|
+
|
148
|
+
CREATE TABLE post_medias(
|
149
|
+
id serial PRIMARY KEY,
|
150
|
+
post_id integer NOT NULL REFERENCES posts,
|
151
|
+
media_id integer NOT NULL REFERENCES medias
|
152
|
+
);
|
data/spec/factories.rb
CHANGED
@@ -33,4 +33,19 @@ FactoryGirl.define do
|
|
33
33
|
author
|
34
34
|
url { Faker::Avatar.image }
|
35
35
|
end
|
36
|
+
|
37
|
+
factory :comment do
|
38
|
+
post
|
39
|
+
name { Faker::Name.name }
|
40
|
+
body { Faker::Lorem.paragraph }
|
41
|
+
end
|
42
|
+
|
43
|
+
factory :media do
|
44
|
+
url { Faker::Internet.url }
|
45
|
+
end
|
46
|
+
|
47
|
+
factory :post_media do
|
48
|
+
post
|
49
|
+
media
|
50
|
+
end
|
36
51
|
end
|
data/spec/json/json_spec.rb
CHANGED
@@ -194,6 +194,60 @@ describe 'json' do
|
|
194
194
|
find_json = Oj.load User.find_json(user.id, include: {posts: {columns: [:id], include: :forum}})
|
195
195
|
expect(find_json).to eq(to_json)
|
196
196
|
end
|
197
|
+
|
198
|
+
context 'assocation table has the belongs_to' do
|
199
|
+
it 'includes entire has_many through association' do
|
200
|
+
user = FactoryGirl.create :user
|
201
|
+
post = FactoryGirl.create :post, author: user
|
202
|
+
FactoryGirl.create :comment, post: post
|
203
|
+
FactoryGirl.create :comment, post: post
|
204
|
+
|
205
|
+
to_json = Oj.load user.to_json(include: :comments)
|
206
|
+
find_json = Oj.load User.find_json(user.id, include: :comments)
|
207
|
+
expect(find_json).to eq(to_json)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'excludes other has_many through association records' do
|
211
|
+
user = FactoryGirl.create :user
|
212
|
+
post = FactoryGirl.create :post, author: user
|
213
|
+
FactoryGirl.create :comment, post: post
|
214
|
+
FactoryGirl.create :comment, post: post
|
215
|
+
|
216
|
+
other_post = FactoryGirl.create :post, author: user
|
217
|
+
FactoryGirl.create :comment, post: other_post
|
218
|
+
FactoryGirl.create :comment, post: other_post
|
219
|
+
|
220
|
+
to_json = Oj.load user.to_json(include: :comments)
|
221
|
+
find_json = Oj.load User.find_json(user.id, include: :comments)
|
222
|
+
expect(find_json).to eq(to_json)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
context 'through table has the belongs_to' do
|
227
|
+
it 'includes entire has_many through association when ' do
|
228
|
+
post = FactoryGirl.create :post
|
229
|
+
media = FactoryGirl.create :media
|
230
|
+
post.medias << media
|
231
|
+
|
232
|
+
to_json = Oj.load post.to_json(include: :medias)
|
233
|
+
find_json = Oj.load Post.find_json(post.id, include: :medias)
|
234
|
+
expect(find_json).to eq(to_json)
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'excludes other has_many through association records' do
|
238
|
+
post = FactoryGirl.create :post
|
239
|
+
media = FactoryGirl.create :media
|
240
|
+
post.medias << media
|
241
|
+
|
242
|
+
other_post = FactoryGirl.create :post
|
243
|
+
other_media = FactoryGirl.create :media
|
244
|
+
other_post.medias << other_media
|
245
|
+
|
246
|
+
to_json = Oj.load post.to_json(include: :medias)
|
247
|
+
find_json = Oj.load Post.find_json(post.id, include: :medias)
|
248
|
+
expect(find_json).to eq(to_json)
|
249
|
+
end
|
250
|
+
end
|
197
251
|
end
|
198
252
|
end
|
199
253
|
|
data/spec/spec_helper.rb
CHANGED
@@ -27,6 +27,7 @@ class User < ActiveRecord::Base
|
|
27
27
|
-> { where subject: 'foo' },
|
28
28
|
foreign_key: :author_id,
|
29
29
|
class_name: 'Post'
|
30
|
+
has_many :comments, through: :posts
|
30
31
|
|
31
32
|
# association name is reserved word in PostgreSQL
|
32
33
|
has_many :rows, foreign_key: :author_id, class_name: 'Post', table_name: 'posts'
|
@@ -59,12 +60,30 @@ class Post < ActiveRecord::Base
|
|
59
60
|
foreign_key: :forum_id,
|
60
61
|
class_name: 'Forum'
|
61
62
|
has_and_belongs_to_many :tags
|
63
|
+
has_many :comments
|
64
|
+
|
65
|
+
has_many :post_medias
|
66
|
+
has_many :medias, through: :post_medias
|
62
67
|
end
|
63
68
|
|
64
69
|
class Tag < ActiveRecord::Base
|
65
70
|
has_and_belongs_to_many :posts
|
66
71
|
end
|
67
72
|
|
73
|
+
class Comment < ActiveRecord::Base
|
74
|
+
belongs_to :post
|
75
|
+
end
|
76
|
+
|
77
|
+
class Media < ActiveRecord::Base
|
78
|
+
self.table_name = "medias"
|
79
|
+
end
|
80
|
+
|
81
|
+
class PostMedia < ActiveRecord::Base
|
82
|
+
self.table_name = "post_medias"
|
83
|
+
belongs_to :post
|
84
|
+
belongs_to :media
|
85
|
+
end
|
86
|
+
|
68
87
|
FactoryGirl.find_definitions
|
69
88
|
|
70
89
|
RSpec.configure do |config|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: surus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jack Christensen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -193,6 +193,7 @@ files:
|
|
193
193
|
- lib/surus/json/belongs_to_scope_builder.rb
|
194
194
|
- lib/surus/json/has_and_belongs_to_many_scope_builder.rb
|
195
195
|
- lib/surus/json/has_many_scope_builder.rb
|
196
|
+
- lib/surus/json/has_many_through_scope_builder.rb
|
196
197
|
- lib/surus/json/model.rb
|
197
198
|
- lib/surus/json/query.rb
|
198
199
|
- lib/surus/json/row_query.rb
|
@@ -232,7 +233,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
232
233
|
version: '0'
|
233
234
|
requirements: []
|
234
235
|
rubyforge_project: ''
|
235
|
-
rubygems_version: 2.6.
|
236
|
+
rubygems_version: 2.6.13
|
236
237
|
signing_key:
|
237
238
|
specification_version: 4
|
238
239
|
summary: PostgreSQL Acceleration for ActiveRecord
|