calculated_attributes 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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