most_related 0.0.3 → 0.0.4
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/.ruby-version +1 -1
- data/README.md +3 -2
- data/lib/most_related/version.rb +1 -1
- data/lib/most_related.rb +5 -3
- data/most_related.gemspec +12 -7
- data/spec/post_spec.rb +6 -20
- data/spec/spec_helper.rb +15 -2
- data/spec/support/schema.rb +3 -3
- metadata +93 -27
- data/spec/support/string.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b655ee05c62fde06ac5da9dbb806d5b2d46aa2e8
|
4
|
+
data.tar.gz: b716b9ac1370e5fa5f31a1cb6c12a3fa0267c397
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 652d59f88d1a0dfbf6b782dbfa6c9b4cd6d5b61d6eb812470aa5398771ec63f9b53f145a981d03c7d8bfbac1c087da72f73abada3fc2bd42b34ee7f61374ac32
|
7
|
+
data.tar.gz: bd8d55d28bb3c534d440d41a5f447994ccc10ec5439730ed2434900fcc4e27d80134e1001a2080debefeb83e9aeaae3c5a03ba6c25c36d1890ed7274fd8a0664
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.2.2
|
data/README.md
CHANGED
@@ -54,9 +54,10 @@ The count of the many to many associated models in common is accessible on each
|
|
54
54
|
|
55
55
|
post.most_related_count
|
56
56
|
post.most_related_by_tag_count
|
57
|
-
post.
|
57
|
+
post.most_related_by_author_or_tag_count
|
58
58
|
|
59
|
-
If multiple many to many associations are used, the syntax is specific to MySql
|
59
|
+
If multiple many to many associations are used, the syntax is specific to MySql although
|
60
|
+
it could be made to work with Postgres.
|
60
61
|
|
61
62
|
Because of the use of 'group', pagination is not supported.
|
62
63
|
|
data/lib/most_related/version.rb
CHANGED
data/lib/most_related.rb
CHANGED
@@ -35,7 +35,7 @@ module MostRelated
|
|
35
35
|
# post.most_related_by_author_or_tag
|
36
36
|
#
|
37
37
|
# The count of the many to many associated models in common is accessible on each returned model
|
38
|
-
# eg post.most_related_count, post.most_related_by_tag_count and post.
|
38
|
+
# eg post.most_related_count, post.most_related_by_tag_count and post.most_related_by_author_or_tag_count
|
39
39
|
#
|
40
40
|
def has_most_related(many_to_many_associations, as: :most_related)
|
41
41
|
|
@@ -60,6 +60,8 @@ module MostRelated
|
|
60
60
|
joins("INNER JOIN #{join_table} ON #{join_table}.#{foreign_key} = #{table_name}.id")
|
61
61
|
end
|
62
62
|
|
63
|
+
# with postgres, multiple many-to-many associations doesn't work and here's why
|
64
|
+
# http://dba.stackexchange.com/questions/88988/postgres-error-column-must-appear-in-the-group-by-clause-or-be-used-in-an-aggre
|
63
65
|
scope = self.class.select("#{table_name}.*, count(#{table_name}.id) AS #{as}_count").
|
64
66
|
where.not(id: self.id).group("#{table_name}.id").order("#{as}_count DESC")
|
65
67
|
|
@@ -68,7 +70,7 @@ module MostRelated
|
|
68
70
|
scope.merge(association_scopes.first)
|
69
71
|
else
|
70
72
|
# see http://blog.ubersense.com/2013/09/27/tech-talk-unioning-scoped-queries-in-rails/
|
71
|
-
scope.from("((#{association_scopes.map(&:to_sql).join(') UNION ALL (')})) #{table_name}")
|
73
|
+
scope.from("((#{association_scopes.map(&:to_sql).join(') UNION ALL (')})) AS #{table_name}")
|
72
74
|
end
|
73
75
|
end
|
74
76
|
|
@@ -88,4 +90,4 @@ module MostRelated
|
|
88
90
|
end
|
89
91
|
|
90
92
|
# Extend ActiveRecord functionality
|
91
|
-
ActiveRecord::Base.extend MostRelated
|
93
|
+
ActiveRecord::Base.extend MostRelated
|
data/most_related.gemspec
CHANGED
@@ -7,9 +7,9 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "most_related"
|
8
8
|
spec.version = MostRelated::VERSION
|
9
9
|
spec.authors = ["Jolyon Pawlyn"]
|
10
|
-
spec.email = ["
|
11
|
-
spec.description = %q{Adds an instance method to a active record model that returns the most related models based on
|
12
|
-
spec.summary = %q{Returns models that have the most
|
10
|
+
spec.email = ["jpawlyn@gmail.com"]
|
11
|
+
spec.description = %q{Adds an instance method to a active record model that returns the most related models based on associated models in common}
|
12
|
+
spec.summary = %q{Returns models that have the most associated models in common}
|
13
13
|
spec.homepage = "https://github.com/jpawlyn/most_related"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -18,8 +18,13 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.
|
22
|
-
spec.
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
21
|
+
spec.required_ruby_version = '>= 1.9.3'
|
22
|
+
spec.add_runtime_dependency 'activerecord', '~> 4.0', '>= 4.0.0'
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
24
|
+
spec.add_development_dependency 'rspec', '~> 2.14', '>= 2.14.1'
|
25
|
+
spec.add_development_dependency 'database_cleaner', '~>1.4'
|
26
|
+
spec.add_development_dependency 'sqlite3', '~>1.3'
|
27
|
+
spec.add_development_dependency 'mysql2', '~>0.3'
|
28
|
+
spec.add_development_dependency 'pg', '~>0.18'
|
29
|
+
spec.add_development_dependency 'byebug', '~>4.0'
|
25
30
|
end
|
data/spec/post_spec.rb
CHANGED
@@ -37,30 +37,16 @@ describe Post do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
context "combination of 'has_many through:' and habtm" do
|
40
|
-
let(:post) { Post.create! authors: [author1, author2, author3], tags: [tag1, tag2, tag3] }
|
41
|
-
let(:post1) { Post.create! authors: [author1, author2, author3], tags: [tag1, tag2, tag4] }
|
42
|
-
let(:post2) { Post.create! authors: [author1, author4] }
|
43
|
-
let(:post3) { Post.create! tags: [tag4] }
|
44
|
-
let(:post4) { Post.create! authors: [author1], tags: [tag1, tag2, tag3] }
|
40
|
+
let!(:post) { Post.create! authors: [author1, author2, author3], tags: [tag1, tag2, tag3] }
|
41
|
+
let!(:post1) { Post.create! authors: [author1, author2, author3], tags: [tag1, tag2, tag4] }
|
42
|
+
let!(:post2) { Post.create! authors: [author1, author4] }
|
43
|
+
let!(:post3) { Post.create! tags: [tag4] }
|
44
|
+
let!(:post4) { Post.create! authors: [author1], tags: [tag1, tag2, tag3] }
|
45
45
|
|
46
46
|
it 'return posts that have the most authors and tags in common with post' do
|
47
|
-
|
47
|
+
# note, this test currently only passes with MySQL
|
48
48
|
expect(post.most_related_by_author_or_tag.map(&:most_related_by_author_or_tag_count)).to eq([5, 4, 1])
|
49
49
|
expect(post.most_related_by_author_or_tag).to eq([post1, post4, post2])
|
50
50
|
end
|
51
|
-
|
52
|
-
it 'sql check' do
|
53
|
-
expect(post.most_related_by_author_or_tag.where_clauses).to eq(["(\"posts\".\"id\" != #{post.id})"])
|
54
|
-
expect(post.most_related_by_author_or_tag.order_clauses).to eq(["most_related_by_author_or_tag_count DESC"])
|
55
|
-
sql = <<-eos
|
56
|
-
SELECT posts.*, count(posts.id) AS most_related_by_author_or_tag_count FROM
|
57
|
-
((SELECT \"posts\".* FROM \"posts\" INNER JOIN author_posts ON author_posts.post_id = posts.id WHERE
|
58
|
-
(author_posts.author_id IN (select author_posts.author_id from author_posts where author_posts.post_id = #{post.id})))
|
59
|
-
UNION ALL (SELECT \"posts\".* FROM \"posts\" INNER JOIN posts_tags ON posts_tags.post_id = posts.id WHERE
|
60
|
-
(posts_tags.tag_id IN (select posts_tags.tag_id from posts_tags where posts_tags.post_id = #{post.id})))) posts
|
61
|
-
WHERE (\"posts\".\"id\" != #{post.id}) GROUP BY posts.id ORDER BY most_related_by_author_or_tag_count DESC
|
62
|
-
eos
|
63
|
-
expect(post.most_related_by_author_or_tag.to_sql.squish!).to eq(sql.squish!)
|
64
|
-
end
|
65
51
|
end
|
66
52
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -6,13 +6,18 @@
|
|
6
6
|
|
7
7
|
# see http://blog.markstarkman.com/blog/2013/01/23/using-sqlite-to-test-active-record-models/
|
8
8
|
require 'active_record'
|
9
|
-
|
9
|
+
|
10
|
+
ActiveRecord::Base.establish_connection adapter: 'mysql2', database: 'most_related'
|
11
|
+
# ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
|
12
|
+
# ActiveRecord::Base.establish_connection adapter: 'postgresql', database: 'most_related'
|
10
13
|
load 'support/schema.rb'
|
11
14
|
|
12
15
|
require 'most_related'
|
13
16
|
require 'support/models'
|
14
|
-
require '
|
17
|
+
require 'database_cleaner'
|
18
|
+
require 'byebug'
|
15
19
|
|
20
|
+
DatabaseCleaner.strategy = :transaction
|
16
21
|
|
17
22
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
18
23
|
RSpec.configure do |config|
|
@@ -25,4 +30,12 @@ RSpec.configure do |config|
|
|
25
30
|
# the seed, which is printed after each run.
|
26
31
|
# --seed 1234
|
27
32
|
config.order = 'random'
|
33
|
+
|
34
|
+
config.before :each do
|
35
|
+
DatabaseCleaner.start
|
36
|
+
end
|
37
|
+
|
38
|
+
config.after :each do
|
39
|
+
DatabaseCleaner.clean
|
40
|
+
end
|
28
41
|
end
|
data/spec/support/schema.rb
CHANGED
@@ -2,17 +2,17 @@ ActiveRecord::Schema.define do
|
|
2
2
|
self.verbose = false
|
3
3
|
|
4
4
|
create_table :authors, force: true do |t|
|
5
|
-
t.timestamps
|
5
|
+
t.timestamps null: false
|
6
6
|
end
|
7
7
|
|
8
8
|
create_table :author_posts, force: true do |t|
|
9
9
|
t.integer :author_id, null: false
|
10
10
|
t.integer :post_id, null: false
|
11
|
-
t.timestamps
|
11
|
+
t.timestamps null: false
|
12
12
|
end
|
13
13
|
|
14
14
|
create_table :posts, force: true do |t|
|
15
|
-
t.timestamps
|
15
|
+
t.timestamps null: false
|
16
16
|
end
|
17
17
|
|
18
18
|
create_table :posts_tags, force: true do |t|
|
metadata
CHANGED
@@ -1,82 +1,150 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: most_related
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jolyon Pawlyn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 4.0.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.0'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 4.0.0
|
13
33
|
- !ruby/object:Gem::Dependency
|
14
34
|
name: bundler
|
15
35
|
requirement: !ruby/object:Gem::Requirement
|
16
36
|
requirements:
|
17
|
-
- - ~>
|
37
|
+
- - "~>"
|
18
38
|
- !ruby/object:Gem::Version
|
19
39
|
version: '1.3'
|
20
40
|
type: :development
|
21
41
|
prerelease: false
|
22
42
|
version_requirements: !ruby/object:Gem::Requirement
|
23
43
|
requirements:
|
24
|
-
- - ~>
|
44
|
+
- - "~>"
|
25
45
|
- !ruby/object:Gem::Version
|
26
46
|
version: '1.3'
|
27
47
|
- !ruby/object:Gem::Dependency
|
28
48
|
name: rspec
|
29
49
|
requirement: !ruby/object:Gem::Requirement
|
30
50
|
requirements:
|
31
|
-
- - ~>
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.14'
|
54
|
+
- - ">="
|
32
55
|
- !ruby/object:Gem::Version
|
33
56
|
version: 2.14.1
|
34
57
|
type: :development
|
35
58
|
prerelease: false
|
36
59
|
version_requirements: !ruby/object:Gem::Requirement
|
37
60
|
requirements:
|
38
|
-
- - ~>
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '2.14'
|
64
|
+
- - ">="
|
39
65
|
- !ruby/object:Gem::Version
|
40
66
|
version: 2.14.1
|
41
67
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
68
|
+
name: database_cleaner
|
43
69
|
requirement: !ruby/object:Gem::Requirement
|
44
70
|
requirements:
|
45
|
-
- - ~>
|
71
|
+
- - "~>"
|
46
72
|
- !ruby/object:Gem::Version
|
47
|
-
version: 4
|
73
|
+
version: '1.4'
|
48
74
|
type: :development
|
49
75
|
prerelease: false
|
50
76
|
version_requirements: !ruby/object:Gem::Requirement
|
51
77
|
requirements:
|
52
|
-
- - ~>
|
78
|
+
- - "~>"
|
53
79
|
- !ruby/object:Gem::Version
|
54
|
-
version: 4
|
80
|
+
version: '1.4'
|
55
81
|
- !ruby/object:Gem::Dependency
|
56
82
|
name: sqlite3
|
57
83
|
requirement: !ruby/object:Gem::Requirement
|
58
84
|
requirements:
|
59
|
-
- -
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '1.3'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - "~>"
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '1.3'
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: mysql2
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - "~>"
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0.3'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - "~>"
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0.3'
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
name: pg
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - "~>"
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0.18'
|
116
|
+
type: :development
|
117
|
+
prerelease: false
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - "~>"
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0.18'
|
123
|
+
- !ruby/object:Gem::Dependency
|
124
|
+
name: byebug
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - "~>"
|
60
128
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
129
|
+
version: '4.0'
|
62
130
|
type: :development
|
63
131
|
prerelease: false
|
64
132
|
version_requirements: !ruby/object:Gem::Requirement
|
65
133
|
requirements:
|
66
|
-
- -
|
134
|
+
- - "~>"
|
67
135
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
136
|
+
version: '4.0'
|
69
137
|
description: Adds an instance method to a active record model that returns the most
|
70
|
-
related models based on
|
138
|
+
related models based on associated models in common
|
71
139
|
email:
|
72
|
-
-
|
140
|
+
- jpawlyn@gmail.com
|
73
141
|
executables: []
|
74
142
|
extensions: []
|
75
143
|
extra_rdoc_files: []
|
76
144
|
files:
|
77
|
-
- .gitignore
|
78
|
-
- .rspec
|
79
|
-
- .ruby-version
|
145
|
+
- ".gitignore"
|
146
|
+
- ".rspec"
|
147
|
+
- ".ruby-version"
|
80
148
|
- Gemfile
|
81
149
|
- LICENSE.txt
|
82
150
|
- README.md
|
@@ -88,7 +156,6 @@ files:
|
|
88
156
|
- spec/spec_helper.rb
|
89
157
|
- spec/support/models.rb
|
90
158
|
- spec/support/schema.rb
|
91
|
-
- spec/support/string.rb
|
92
159
|
homepage: https://github.com/jpawlyn/most_related
|
93
160
|
licenses:
|
94
161
|
- MIT
|
@@ -99,23 +166,22 @@ require_paths:
|
|
99
166
|
- lib
|
100
167
|
required_ruby_version: !ruby/object:Gem::Requirement
|
101
168
|
requirements:
|
102
|
-
- -
|
169
|
+
- - ">="
|
103
170
|
- !ruby/object:Gem::Version
|
104
|
-
version:
|
171
|
+
version: 1.9.3
|
105
172
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
173
|
requirements:
|
107
|
-
- -
|
174
|
+
- - ">="
|
108
175
|
- !ruby/object:Gem::Version
|
109
176
|
version: '0'
|
110
177
|
requirements: []
|
111
178
|
rubyforge_project:
|
112
|
-
rubygems_version: 2.
|
179
|
+
rubygems_version: 2.4.5
|
113
180
|
signing_key:
|
114
181
|
specification_version: 4
|
115
|
-
summary: Returns models that have the most
|
182
|
+
summary: Returns models that have the most associated models in common
|
116
183
|
test_files:
|
117
184
|
- spec/post_spec.rb
|
118
185
|
- spec/spec_helper.rb
|
119
186
|
- spec/support/models.rb
|
120
187
|
- spec/support/schema.rb
|
121
|
-
- spec/support/string.rb
|