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 +4 -4
- data/gemfiles/rails3.gemfile.lock +1 -1
- data/gemfiles/rails4_1.gemfile.lock +1 -1
- data/gemfiles/rails4_2.gemfile.lock +1 -1
- data/lib/calculated_attributes/model_methods.rb +8 -1
- data/lib/calculated_attributes/rails_4_patches.rb +5 -3
- data/lib/calculated_attributes/version.rb +1 -1
- data/spec/lib/calculated_attributes_spec.rb +41 -17
- data/spec/support/models.rb +12 -1
- data/spec/support/schema.rb +6 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a15804206f8ef6a215d616b036b8019c4bea1754
|
4
|
+
data.tar.gz: 36be65afdbe2ca7018547f9d77250b2d516c98d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e86e989c7ff52c20586dfea1135dafd77eb62b2c2aefbd62d46b7d1d5cd99c1bf88957289ffdb33a5e5b8704faef6e3ee7d415352d04d633c052abab8e79f5d
|
7
|
+
data.tar.gz: 02463a40ef5fc7ecc63fc351a1cbb81702a2566060ff69dc68b9eb54ea51db2e1af4fc87de4811a43bb360e32041092c07e2ecab733c324abf7bbc95e3033247
|
@@ -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 =
|
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 |
|
36
|
-
|
37
|
-
|
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
|
|
@@ -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(:
|
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(:
|
18
|
-
expect(post.
|
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(:
|
24
|
-
expect(post.
|
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(:
|
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(:
|
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(:
|
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.
|
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.
|
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(:
|
62
|
-
expect(post.
|
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(:
|
72
|
-
expect(Post.where("posts.text = 'First post!'").calculated(:
|
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(:
|
77
|
-
expect(model_scoped(Post).calculated(:
|
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(:
|
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
|
data/spec/support/models.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
class Post < ActiveRecord::Base
|
2
|
-
|
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
|
data/spec/support/schema.rb
CHANGED
@@ -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.
|
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-
|
11
|
+
date: 2015-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: appraisal
|