calculated_attributes 0.1.1 → 0.1.2

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: 6e9af41ada6b87c3d05e4d8a3e47ccebb28b2a3b
4
- data.tar.gz: 4bf3d866adaf0a9fd07bdfc7bdb8b6a2e2e42857
3
+ metadata.gz: a15804206f8ef6a215d616b036b8019c4bea1754
4
+ data.tar.gz: 36be65afdbe2ca7018547f9d77250b2d516c98d9
5
5
  SHA512:
6
- metadata.gz: d43f7a046648b0a1dd8a26313cfeffc1d814653c31216c324521e8aab85ce981b58969c7a005f54b5c4fb88062ac63a592f7968c77aee93110da23878f43d617
7
- data.tar.gz: 10ebe98f3b66530b26fcc85f8f279a58801d2454f3126a4de98d79c6bae2b646f7a8ad69356e0dd81cb917e5a69724ff13d70d040f2569d0514aef41ee90df8d
6
+ metadata.gz: 2e86e989c7ff52c20586dfea1135dafd77eb62b2c2aefbd62d46b7d1d5cd99c1bf88957289ffdb33a5e5b8704faef6e3ee7d415352d04d633c052abab8e79f5d
7
+ data.tar.gz: 02463a40ef5fc7ecc63fc351a1cbb81702a2566060ff69dc68b9eb54ea51db2e1af4fc87de4811a43bb360e32041092c07e2ecab733c324abf7bbc95e3033247
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../
3
3
  specs:
4
- calculated_attributes (0.1.1)
4
+ calculated_attributes (0.1.2)
5
5
  activerecord (>= 3.2.20)
6
6
 
7
7
  GEM
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../
3
3
  specs:
4
- calculated_attributes (0.1.1)
4
+ calculated_attributes (0.1.2)
5
5
  activerecord (>= 3.2.20)
6
6
 
7
7
  GEM
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../
3
3
  specs:
4
- calculated_attributes (0.1.1)
4
+ calculated_attributes (0.1.2)
5
5
  activerecord (>= 3.2.20)
6
6
 
7
7
  GEM
@@ -70,7 +70,14 @@ ActiveRecord::Relation.send(:include, Module.new do
70
70
  args.each do |arg|
71
71
  lam = klass.calculated.calculated[arg] || klass.base_class.calculated.calculated[arg]
72
72
  sql = lam.call
73
- new_projection = sql.is_a?(String) ? Arel.sql("(#{sql})").as(arg.to_s) : sql.as(arg.to_s)
73
+ new_projection =
74
+ if sql.is_a?(String)
75
+ Arel.sql("(#{sql})").as(arg.to_s)
76
+ elsif sql.respond_to? :to_sql
77
+ Arel.sql("(#{sql.to_sql})").as(arg.to_s)
78
+ else
79
+ sql.as(arg.to_s)
80
+ end
74
81
  new_projection.calculated_attr!
75
82
  projections.push new_projection
76
83
  end
@@ -32,9 +32,11 @@ module ActiveRecord
32
32
  def instantiate(result_set, aliases)
33
33
  primary_key = aliases.column_alias(join_root, join_root.primary_key)
34
34
 
35
- seen = Hash.new do |i, object_id|
36
- i[object_id] = Hash.new do |j, child_class|
37
- j[child_class] = {}
35
+ seen = Hash.new do |k, primary_key|
36
+ Hash.new do |i, object_id|
37
+ i[object_id] = Hash.new do |j, child_class|
38
+ j[child_class] = {}
39
+ end
38
40
  end
39
41
  end
40
42
 
@@ -1,3 +1,3 @@
1
1
  module CalculatedAttributes
2
- VERSION = '0.1.1'
2
+ VERSION = '0.1.2'
3
3
  end
@@ -10,39 +10,39 @@ end
10
10
 
11
11
  describe 'calculated_attributes' do
12
12
  it 'includes calculated attributes' do
13
- expect(model_scoped(Post).calculated(:comments).first.comments).to eq(1)
13
+ expect(model_scoped(Post).calculated(:comments_count).first.comments_count).to eq(1)
14
14
  end
15
15
 
16
16
  it 'includes multiple calculated attributes' do
17
- post = model_scoped(Post).calculated(:comments, :comments_two).first
18
- expect(post.comments).to eq(1)
17
+ post = model_scoped(Post).calculated(:comments_count, :comments_two).first
18
+ expect(post.comments_count).to eq(1)
19
19
  expect(post.comments_two).to eq(1)
20
20
  end
21
21
 
22
22
  it 'includes chained calculated attributes' do
23
- post = model_scoped(Post).calculated(:comments).calculated(:comments_two).first
24
- expect(post.comments).to eq(1)
23
+ post = model_scoped(Post).calculated(:comments_count).calculated(:comments_two).first
24
+ expect(post.comments_count).to eq(1)
25
25
  expect(post.comments_two).to eq(1)
26
26
  end
27
27
 
28
28
  it 'nests with where query' do
29
- expect(Post.where(id: 1).calculated(:comments).first.comments).to eq(1)
29
+ expect(Post.where(id: 1).calculated(:comments_count).first.comments_count).to eq(1)
30
30
  end
31
31
 
32
32
  it 'nests with order query' do
33
- expect(Post.order('id DESC').calculated(:comments).first.id).to eq(Post.count)
33
+ expect(Post.order('id DESC').calculated(:comments_count).first.id).to eq(Post.count)
34
34
  end
35
35
 
36
36
  it 'allows access via model instance method' do
37
- expect(Post.first.calculated(:comments).comments).to eq(1)
37
+ expect(Post.first.calculated(:comments_count).comments_count).to eq(1)
38
38
  end
39
39
 
40
40
  it 'allows anonymous access via model instance method' do
41
- expect(Post.first.comments).to eq(1)
41
+ expect(Post.first.comments_count).to eq(1)
42
42
  end
43
43
 
44
44
  it 'allows anonymous access via model instance method with STI and lambda on base class' do
45
- expect(Tutorial.first.comments).to eq(1)
45
+ expect(Tutorial.first.comments_count).to eq(1)
46
46
  end
47
47
 
48
48
  it 'allows anonymous access via model instance method with STI and lambda on subclass' do
@@ -58,8 +58,8 @@ describe 'calculated_attributes' do
58
58
  end
59
59
 
60
60
  it 'allows access to multiple calculated attributes via model instance method' do
61
- post = Post.first.calculated(:comments, :comments_two)
62
- expect(post.comments).to eq(1)
61
+ post = Post.first.calculated(:comments_count, :comments_two)
62
+ expect(post.comments_count).to eq(1)
63
63
  expect(post.comments_two).to eq(1)
64
64
  end
65
65
 
@@ -67,21 +67,45 @@ describe 'calculated_attributes' do
67
67
  expect(model_scoped(Post).calculated(:comments_arel).first.comments_arel).to eq(1)
68
68
  end
69
69
 
70
+ it 'allows attributes to be defined using class that responds to to_sql' do
71
+ expect(model_scoped(Post).calculated(:comments_to_sql).first.comments_to_sql).to eq(1)
72
+ end
73
+
70
74
  it 'maintains previous scope' do
71
- expect(Post.where(text: 'First post!').calculated(:comments).first.comments).to eq(1)
72
- expect(Post.where("posts.text = 'First post!'").calculated(:comments).first.comments).to eq(1)
75
+ expect(Post.where(text: 'First post!').calculated(:comments_count).first.comments_count).to eq(1)
76
+ expect(Post.where("posts.text = 'First post!'").calculated(:comments_count).first.comments_count).to eq(1)
73
77
  end
74
78
 
75
79
  it 'maintains subsequent scope' do
76
- expect(model_scoped(Post).calculated(:comments).where(text: 'First post!').first.comments).to eq(1)
77
- expect(model_scoped(Post).calculated(:comments).where("posts.text = 'First post!'").first.comments).to eq(1)
80
+ expect(model_scoped(Post).calculated(:comments_count).where(text: 'First post!').first.comments_count).to eq(1)
81
+ expect(model_scoped(Post).calculated(:comments_count).where("posts.text = 'First post!'").first.comments_count).to eq(1)
78
82
  end
79
83
 
80
84
  it 'includes calculated attributes with STI and lambda on base class' do
81
- expect(model_scoped(Tutorial).calculated(:comments).first.comments).to eq(1)
85
+ expect(model_scoped(Tutorial).calculated(:comments_count).first.comments_count).to eq(1)
82
86
  end
83
87
 
84
88
  it 'includes calculated attributes with STI and lambda on subclass' do
85
89
  expect(model_scoped(Article).calculated(:sub_comments).first.sub_comments).to eq(1)
86
90
  end
91
+
92
+ context 'when joining models' do
93
+ it 'includes calculated attributes' do
94
+ expect(model_scoped(Post).joins(:comments).calculated(:comments_count).first.comments_count).to eq(1)
95
+ end
96
+
97
+ context 'when conditions are specified on the joined table' do
98
+ it 'includes calculated models' do
99
+ scope = model_scoped(Post).joins(:comments)
100
+ expect(scope.first.comments_count).to eq(1)
101
+ end
102
+ end
103
+ end
104
+
105
+ context 'when eager loading models' do
106
+ it 'includes calculated attributes' do
107
+ scope = model_scoped(Post).includes(:comments).references(:comments)
108
+ expect(scope.first.comments_count).to eq(1)
109
+ end
110
+ end
87
111
  end
@@ -1,7 +1,11 @@
1
1
  class Post < ActiveRecord::Base
2
- calculated :comments, -> { 'select count(*) from comments where comments.post_id = posts.id' }
2
+ has_many :comments
3
+ belongs_to :user
4
+
5
+ calculated :comments_count, -> { 'select count(*) from comments where comments.post_id = posts.id' }
3
6
  calculated :comments_two, -> { 'select count(*) from comments where comments.post_id = posts.id' }
4
7
  calculated :comments_arel, -> { Comment.where(Comment.arel_table[:post_id].eq(Post.arel_table[:id])).select(Arel.sql('count(*)')) }
8
+ calculated :comments_to_sql, -> { Comment.where('comments.post_id = posts.id').select('count(*)') }
5
9
  end
6
10
 
7
11
  class Tutorial < Post
@@ -12,4 +16,11 @@ class Article < Post
12
16
  end
13
17
 
14
18
  class Comment < ActiveRecord::Base
19
+ belongs_to :post
20
+ belongs_to :user
21
+ end
22
+
23
+ class User < ActiveRecord::Base
24
+ has_many :comments
25
+ has_many :posts
15
26
  end
@@ -3,12 +3,18 @@ ActiveRecord::Schema.define do
3
3
 
4
4
  create_table :posts, force: true do |t|
5
5
  t.string :text
6
+ t.references :user
6
7
  t.timestamps null: false
7
8
  end
8
9
 
9
10
  create_table :comments, force: true do |t|
10
11
  t.integer :post_id
11
12
  t.string :text
13
+ t.references :user
12
14
  t.timestamps null: false
13
15
  end
16
+
17
+ create_table :users, force: true do |t|
18
+ t.string :username
19
+ end
14
20
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: calculated_attributes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zach Schneider
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-27 00:00:00.000000000 Z
11
+ date: 2015-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal