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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ca553e879baa56ea3b059072ecb5cdfbdfc148f4
4
- data.tar.gz: 9284d9fc51b2d3b50c013e19e77b13a8ce1f8cbe
3
+ metadata.gz: 0ba3e32fb91f29014a44a70df352f6863ee8f341
4
+ data.tar.gz: a7dd13115acd96b38f3369750a05596912a2a90b
5
5
  SHA512:
6
- metadata.gz: 818f420d11fd94a7e90d67855cdb5e79db3aac8c5d73c08608012e46ee8c73f1067a1555730c369c3817d2ba6dcc36d34a4b79121334cc78fc2c97dcedf82b0e
7
- data.tar.gz: 4131b91df11f7186e7260b0aed8d87079ed124f7f03fe253bcd80dd35d1068e96f188fd0914251df8c1a8443132cfd1d5a99bfdde3e30f9e59e9d20450aa7cf4
6
+ metadata.gz: fef906f19243ce07000434326b9be81742a4de4ae8f969a526d624ed19b69f36a23834e47d78aad02c296b3f3428411ff20359f998bc6d5d72cef93c2e1a08be
7
+ data.tar.gz: 886eabfb959223927da81e2ad0dc11977f6b8081861ec1c20211f5955abeb35e74331119b15b745d879c612a8dacf00154f85d04f998a7479e8e5da9854e5e34
@@ -1,3 +1,7 @@
1
+ # 0.7.0 (October 2, 2017)
2
+
3
+ * Support JSON has_many :though relationships (Peter Schilling)
4
+
1
5
  # 0.6.5 (May 5, 2017)
2
6
 
3
7
  * Qualify column references with table names (Zach Schneider)
@@ -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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Surus
2
- VERSION = "0.6.5"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -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
+ );
@@ -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
@@ -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
 
@@ -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.6.5
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-05-05 00:00:00.000000000 Z
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.11
236
+ rubygems_version: 2.6.13
236
237
  signing_key:
237
238
  specification_version: 4
238
239
  summary: PostgreSQL Acceleration for ActiveRecord