similar_models 0.2.1 → 0.4.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 +5 -5
- data/.ruby-version +1 -1
- data/README.md +75 -39
- data/lib/similar_models/version.rb +1 -1
- data/lib/similar_models.rb +44 -7
- data/similar_models.gemspec +7 -8
- data/spec/post_spec.rb +49 -21
- data/spec/spec_helper.rb +1 -1
- metadata +18 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2bf02e51c067023b861f64a73394be810f74ed007a4299a4cc4de18fb7e8ff71
|
4
|
+
data.tar.gz: ae0fdceeb1388fa7a247c89d892d812c2554ffb0c7f12c1389da6b313b3b3350
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ac48f199b64dc571a9f05caf15128429b809988d8d904750870fa30db3b74a3a5bb5a650862b3b97ce331bd5b9c250efe4efb090c96552c2610da8dbed46760
|
7
|
+
data.tar.gz: d0bbb042025768241fcc2b487b9767e19fbd8244f79653d213908added72df10a9368daba02f192390954ebf5f96618b035b49ae4dabbeae0d8c156a629d3dca
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.4.2
|
data/README.md
CHANGED
@@ -1,80 +1,116 @@
|
|
1
1
|
# Similar Models
|
2
2
|
|
3
|
-
Adds a `similar_{
|
3
|
+
Adds a `similar_#{model_name.plural}` instance and class method to an active record model, but can be set to any name using `as: {method name}`.
|
4
4
|
|
5
|
-
The
|
5
|
+
The instance method returns models that have associated models in common ordered by most in common first.
|
6
|
+
|
7
|
+
The class method returns models ordered by most associated models in common.
|
8
|
+
|
9
|
+
If the commonality count is the same then a second order clause of `created_at` if present takes precedence.
|
10
|
+
|
11
|
+
The association(s) have to be many to many, so either [habtm](https://guides.rubyonrails.org/association_basics.html#has-and-belongs-to-many) or [has_many :through](https://guides.rubyonrails.org/association_basics.html#has-many-through).
|
6
12
|
|
7
13
|
## Installation
|
8
14
|
|
9
15
|
Add this line to your application's Gemfile:
|
10
16
|
|
11
|
-
|
17
|
+
```sh
|
18
|
+
gem 'similar_models'
|
19
|
+
```
|
12
20
|
|
13
21
|
And then execute:
|
14
22
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
$ gem install similar_models
|
23
|
+
```sh
|
24
|
+
$ bundle
|
25
|
+
```
|
20
26
|
|
21
27
|
## Usage
|
22
28
|
|
23
29
|
Post example
|
24
30
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
31
|
+
```ruby
|
32
|
+
class Post < ApplicationRecord
|
33
|
+
has_many :author_posts
|
34
|
+
has_many :authors, through: :author_posts
|
35
|
+
has_and_belongs_to_many :tags
|
29
36
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
37
|
+
has_similar_models :authors
|
38
|
+
has_similar_models :tags, as: :similar_posts_by_tag
|
39
|
+
has_similar_models :authors, :tags, as: :similar_posts_by_author_and_tag
|
40
|
+
end
|
34
41
|
|
35
|
-
|
36
|
-
|
42
|
+
class Tag < ApplicationRecord
|
43
|
+
end
|
37
44
|
|
38
|
-
|
39
|
-
|
40
|
-
|
45
|
+
class Author < ApplicationRecord
|
46
|
+
has_many :author_posts
|
47
|
+
end
|
41
48
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
49
|
+
class AuthorPosts < ApplicationRecord
|
50
|
+
belongs_to :author
|
51
|
+
belongs_to :post
|
52
|
+
end
|
53
|
+
```
|
46
54
|
|
47
|
-
To return
|
55
|
+
To return posts with authors in common with the `post` model by most in common first:
|
48
56
|
|
49
|
-
|
57
|
+
```ruby
|
58
|
+
post.similar_posts
|
59
|
+
```
|
60
|
+
|
61
|
+
To return posts ordered by most authors in common:
|
62
|
+
```ruby
|
63
|
+
Post.similar_posts
|
64
|
+
```
|
50
65
|
|
51
66
|
The returned object is an ActiveRecord::Relation and so chaining of other query methods is possible:
|
52
67
|
|
53
|
-
|
68
|
+
```ruby
|
69
|
+
post.similar_posts.where(created_at: 10.days.ago..).limit(5)
|
70
|
+
```
|
71
|
+
|
72
|
+
To return posts with tags in common with the `post` model by most in common first:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
post.similar_posts_by_tag
|
76
|
+
```
|
77
|
+
|
78
|
+
To return posts ordered by most tags in common:
|
79
|
+
```ruby
|
80
|
+
Post.similar_posts_by_tag
|
81
|
+
```
|
54
82
|
|
55
|
-
To return
|
83
|
+
To return posts with the authors and tags in common with the `post` model by most in common first:
|
56
84
|
|
57
|
-
|
85
|
+
```ruby
|
86
|
+
post.similar_posts_by_author_and_tag
|
87
|
+
```
|
58
88
|
|
59
|
-
To return
|
89
|
+
To return posts ordered by most authors and tags in common:
|
60
90
|
|
61
|
-
|
91
|
+
```ruby
|
92
|
+
Post.similar_posts_by_author_and_tag
|
93
|
+
```
|
62
94
|
|
63
95
|
The count of the associated models in common is accessible on each returned model:
|
64
96
|
|
65
|
-
|
66
|
-
|
67
|
-
|
97
|
+
```ruby
|
98
|
+
post.similar_posts_commonality_count
|
99
|
+
post.similar_posts_by_tag_commonality_count
|
100
|
+
post.similar_posts_by_author_and_tag_commonality_count
|
101
|
+
```
|
68
102
|
|
69
|
-
Note multiple associations do not work with sqlite
|
103
|
+
**Note multiple associations for the instance method do not work with sqlite.**
|
70
104
|
|
71
|
-
|
105
|
+
**Pagination is not supported on the instance method due to the use of `group by`.**
|
72
106
|
|
73
107
|
## In conjunction with acts-as-taggable-on
|
74
108
|
|
75
|
-
If you use https://github.com/mbleigh/acts-as-taggable-on/#usage and want to find related users say across multiple contexts:
|
109
|
+
If you use [mbleigh/acts-as-taggable-on](https://github.com/mbleigh/acts-as-taggable-on/#usage) and want to find related users say across multiple contexts:
|
76
110
|
|
77
|
-
|
111
|
+
```ruby
|
112
|
+
user.similar_users.where(taggings: { context: %w(skills interests) })
|
113
|
+
```
|
78
114
|
|
79
115
|
## Contributing
|
80
116
|
|
data/lib/similar_models.rb
CHANGED
@@ -3,9 +3,45 @@ require 'similar_models/version'
|
|
3
3
|
module SimilarModels
|
4
4
|
|
5
5
|
def has_similar_models(*many_to_many_associations, as: nil)
|
6
|
-
as
|
6
|
+
as ||= "similar_#{model_name.plural}"
|
7
7
|
|
8
|
-
#
|
8
|
+
# example sql query for one many to many association:
|
9
|
+
#
|
10
|
+
# SELECT posts.*,
|
11
|
+
# (select count(*) from author_posts where post_id != posts.alt_id and author_id in
|
12
|
+
# (select author_id from author_posts where post_id = posts.alt_id)) AS similar_posts_commonality_count
|
13
|
+
# FROM "posts"
|
14
|
+
# ORDER BY similar_posts_commonality_count DESC, created_at DESC
|
15
|
+
#
|
16
|
+
define_singleton_method as do
|
17
|
+
primary_key_ref = "#{table_name}.#{primary_key}"
|
18
|
+
similarity_counts = []
|
19
|
+
|
20
|
+
many_to_many_associations.each do |many_to_many_association|
|
21
|
+
association = reflect_on_association(many_to_many_association)
|
22
|
+
join_table, foreign_key, association_foreign_key = join_table_values(association)
|
23
|
+
|
24
|
+
similarity_counts <<
|
25
|
+
"(select count(*) from #{join_table} where #{foreign_key} != #{primary_key_ref} and " \
|
26
|
+
"#{association_foreign_key} in " \
|
27
|
+
"(select #{association_foreign_key} from #{join_table} where #{foreign_key} = #{primary_key_ref}))"
|
28
|
+
end
|
29
|
+
|
30
|
+
order_clause = "#{as}_commonality_count DESC"
|
31
|
+
order_clause += ", created_at DESC" if column_names.include?('created_at')
|
32
|
+
select("#{table_name}.*, #{similarity_counts.join(' + ')} AS #{as}_commonality_count").order(order_clause)
|
33
|
+
end
|
34
|
+
|
35
|
+
# example sql query for one many to many association:
|
36
|
+
#
|
37
|
+
# SELECT posts.*, count(posts.alt_id) AS similar_posts_commonality_count
|
38
|
+
# FROM "posts"
|
39
|
+
# INNER JOIN author_posts ON author_posts.post_id = posts.alt_id
|
40
|
+
# WHERE "posts"."alt_id" != ? AND
|
41
|
+
# author_posts.author_id IN (select author_posts.author_id from author_posts where author_posts.post_id = ?)
|
42
|
+
# GROUP BY posts.alt_id, posts.created_at, posts.updated_at
|
43
|
+
# ORDER BY similar_posts_commonality_count DESC, created_at DESC
|
44
|
+
#
|
9
45
|
define_method as do
|
10
46
|
table_name = self.class.table_name
|
11
47
|
primary_key = self.class.primary_key
|
@@ -13,8 +49,8 @@ module SimilarModels
|
|
13
49
|
association_scopes = []
|
14
50
|
|
15
51
|
many_to_many_associations.each do |many_to_many_association|
|
16
|
-
|
17
|
-
join_table, foreign_key, association_foreign_key = self.class.join_table_values(
|
52
|
+
association = self.class.reflect_on_association(many_to_many_association)
|
53
|
+
join_table, foreign_key, association_foreign_key = self.class.join_table_values(association)
|
18
54
|
|
19
55
|
association_scopes << self.class.where(
|
20
56
|
"#{join_table}.#{association_foreign_key} IN \
|
@@ -23,15 +59,16 @@ module SimilarModels
|
|
23
59
|
).joins("INNER JOIN #{join_table} ON #{join_table}.#{foreign_key} = #{primary_key_ref}")
|
24
60
|
end
|
25
61
|
|
26
|
-
|
27
|
-
|
62
|
+
order_clause = "#{as}_commonality_count DESC"
|
63
|
+
order_clause += ", created_at DESC" if self.class.column_names.include?('created_at')
|
64
|
+
scope = self.class.select("#{table_name}.*, count(#{primary_key_ref}) AS #{as}_commonality_count").
|
65
|
+
where.not(primary_key => self.id).order(order_clause)
|
28
66
|
group_by_clause = self.class.column_names.map { |column| "#{table_name}.#{column}"}.join(', ')
|
29
67
|
|
30
68
|
# if there is only one many-to-many association no need to use UNION sql syntax
|
31
69
|
if association_scopes.one?
|
32
70
|
scope.merge(association_scopes.first).group(group_by_clause)
|
33
71
|
else
|
34
|
-
# see http://blog.ubersense.com/2013/09/27/tech-talk-unioning-scoped-queries-in-rails/
|
35
72
|
scope.from("((#{association_scopes.map(&:to_sql).join(') UNION ALL (')})) AS #{table_name}").group(group_by_clause)
|
36
73
|
end
|
37
74
|
end
|
data/similar_models.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = SimilarModels::VERSION
|
9
9
|
spec.authors = ["Jolyon Pawlyn"]
|
10
10
|
spec.email = ["jpawlyn@gmail.com"]
|
11
|
-
spec.description = %q{Adds
|
12
|
-
spec.summary = %q{Returns models that have
|
11
|
+
spec.description = %q{Adds a `similar_#{model_name.plural}` instance and class method to an active record model and returns models based on associated models in common ordered by most in common first}
|
12
|
+
spec.summary = %q{Returns models that have associated models in common ordered by most in common first}
|
13
13
|
spec.homepage = "https://github.com/jpawlyn/similar_models"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -18,13 +18,12 @@ 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.required_ruby_version = '>=
|
22
|
-
spec.add_runtime_dependency 'activerecord', '>=
|
23
|
-
spec.add_development_dependency 'bundler', '~> 1.16'
|
21
|
+
spec.required_ruby_version = '>= 3.1'
|
22
|
+
spec.add_runtime_dependency 'activerecord', '>= 7.2'
|
24
23
|
spec.add_development_dependency 'rspec', '~> 3.5'
|
25
24
|
spec.add_development_dependency 'database_cleaner', '~>1.5'
|
26
|
-
spec.add_development_dependency 'sqlite3', '~>
|
25
|
+
spec.add_development_dependency 'sqlite3', '~>2.6'
|
27
26
|
spec.add_development_dependency 'mysql2', '~>0.5'
|
28
|
-
spec.add_development_dependency 'pg', '~>1.
|
29
|
-
spec.add_development_dependency '
|
27
|
+
spec.add_development_dependency 'pg', '~>1.5'
|
28
|
+
spec.add_development_dependency 'debug', '~>1.0'
|
30
29
|
end
|
data/spec/post_spec.rb
CHANGED
@@ -5,34 +5,52 @@ describe Post do
|
|
5
5
|
let(:author2) { Author.create! }
|
6
6
|
let(:author3) { Author.create! }
|
7
7
|
let(:author4) { Author.create! }
|
8
|
+
let(:author5) { Author.create! }
|
8
9
|
let(:tag1) { Tag.create! }
|
9
10
|
let(:tag2) { Tag.create! }
|
10
11
|
let(:tag3) { Tag.create! }
|
11
12
|
let(:tag4) { Tag.create! }
|
12
13
|
|
13
14
|
context 'has_many through:' do
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
let!(:post) { Post.create! authors: [author1, author2, author3] }
|
16
|
+
let!(:post1) { Post.create! authors: [author1] }
|
17
|
+
let!(:post2) { Post.create! authors: [author4] }
|
18
|
+
let!(:post3) { Post.create! authors: [author1, author2, author3, author4] }
|
19
|
+
let!(:post4) { Post.create! authors: [author5] }
|
20
|
+
|
21
|
+
describe '.similar_posts' do
|
22
|
+
it 'return posts ordered by most authors in common' do
|
23
|
+
expect(described_class.similar_posts.map(&:similar_posts_commonality_count)).to eq([5, 4, 2, 1, 0])
|
24
|
+
expect(described_class.similar_posts).to eq([post3, post, post1, post2, post4])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#similar_posts' do
|
29
|
+
it 'return posts that have authors in common with `post` ordered by most in common first' do
|
30
|
+
expect(post.similar_posts.map(&:similar_posts_commonality_count)).to eq([3, 1])
|
31
|
+
expect(post.similar_posts).to eq([post3, post1])
|
32
|
+
end
|
23
33
|
end
|
24
34
|
end
|
25
35
|
|
26
36
|
context 'has_and_belongs_to_many' do
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
37
|
+
let!(:post) { Post.create! tags: [tag1, tag2, tag3] }
|
38
|
+
let!(:post1) { Post.create! tags: [tag1, tag4] }
|
39
|
+
let!(:post2) { Post.create! tags: [tag2] }
|
40
|
+
let!(:post3) { Post.create! tags: [tag2, tag3] }
|
41
|
+
|
42
|
+
describe '.similar_posts_by_tag' do
|
43
|
+
it 'return posts ordered by most tags in common' do
|
44
|
+
expect(described_class.similar_posts_by_tag.map(&:similar_posts_by_tag_commonality_count)).to eq([4, 3, 2, 1])
|
45
|
+
expect(described_class.similar_posts_by_tag).to eq([post, post3, post2, post1])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#similar_posts_by_tag' do
|
50
|
+
it 'return posts that have tags in common with `post` ordered by most in common first' do
|
51
|
+
expect(post.similar_posts_by_tag.map(&:similar_posts_by_tag_commonality_count)).to eq([2, 1, 1])
|
52
|
+
expect(post.similar_posts_by_tag).to eq([post3, post2, post1])
|
53
|
+
end
|
36
54
|
end
|
37
55
|
end
|
38
56
|
|
@@ -43,9 +61,19 @@ describe Post do
|
|
43
61
|
let!(:post3) { Post.create! tags: [tag4] }
|
44
62
|
let!(:post4) { Post.create! authors: [author1], tags: [tag1, tag2, tag3] }
|
45
63
|
|
46
|
-
|
47
|
-
|
48
|
-
|
64
|
+
describe '.similar_posts_by_author_and_tag' do
|
65
|
+
it 'return posts ordered by most authors and tags in common' do
|
66
|
+
expect(described_class.similar_posts_by_author_and_tag.map(&:similar_posts_by_author_and_tag_commonality_count))
|
67
|
+
.to eq([10, 10, 8, 3, 1])
|
68
|
+
expect(described_class.similar_posts_by_author_and_tag).to eq([post1, post, post4, post2, post3])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#similar_posts_by_author_and_tag' do
|
73
|
+
it 'return posts that have authors and tags in common with `post` ordered by most in common first' do
|
74
|
+
expect(post.similar_posts_by_author_and_tag.map(&:similar_posts_by_author_and_tag_commonality_count)).to eq([5, 4, 1])
|
75
|
+
expect(post.similar_posts_by_author_and_tag).to eq([post1, post4, post2])
|
76
|
+
end
|
49
77
|
end
|
50
78
|
end
|
51
79
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: similar_models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jolyon Pawlyn
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-02-25 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: activerecord
|
@@ -16,28 +15,14 @@ dependencies:
|
|
16
15
|
requirements:
|
17
16
|
- - ">="
|
18
17
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
18
|
+
version: '7.2'
|
20
19
|
type: :runtime
|
21
20
|
prerelease: false
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
23
22
|
requirements:
|
24
23
|
- - ">="
|
25
24
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: bundler
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '1.16'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '1.16'
|
25
|
+
version: '7.2'
|
41
26
|
- !ruby/object:Gem::Dependency
|
42
27
|
name: rspec
|
43
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +57,14 @@ dependencies:
|
|
72
57
|
requirements:
|
73
58
|
- - "~>"
|
74
59
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
60
|
+
version: '2.6'
|
76
61
|
type: :development
|
77
62
|
prerelease: false
|
78
63
|
version_requirements: !ruby/object:Gem::Requirement
|
79
64
|
requirements:
|
80
65
|
- - "~>"
|
81
66
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
67
|
+
version: '2.6'
|
83
68
|
- !ruby/object:Gem::Dependency
|
84
69
|
name: mysql2
|
85
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,30 +85,31 @@ dependencies:
|
|
100
85
|
requirements:
|
101
86
|
- - "~>"
|
102
87
|
- !ruby/object:Gem::Version
|
103
|
-
version: '1.
|
88
|
+
version: '1.5'
|
104
89
|
type: :development
|
105
90
|
prerelease: false
|
106
91
|
version_requirements: !ruby/object:Gem::Requirement
|
107
92
|
requirements:
|
108
93
|
- - "~>"
|
109
94
|
- !ruby/object:Gem::Version
|
110
|
-
version: '1.
|
95
|
+
version: '1.5'
|
111
96
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
97
|
+
name: debug
|
113
98
|
requirement: !ruby/object:Gem::Requirement
|
114
99
|
requirements:
|
115
100
|
- - "~>"
|
116
101
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
102
|
+
version: '1.0'
|
118
103
|
type: :development
|
119
104
|
prerelease: false
|
120
105
|
version_requirements: !ruby/object:Gem::Requirement
|
121
106
|
requirements:
|
122
107
|
- - "~>"
|
123
108
|
- !ruby/object:Gem::Version
|
124
|
-
version: '
|
125
|
-
description: Adds
|
126
|
-
|
109
|
+
version: '1.0'
|
110
|
+
description: Adds a `similar_#{model_name.plural}` instance and class method to an
|
111
|
+
active record model and returns models based on associated models in common ordered
|
112
|
+
by most in common first
|
127
113
|
email:
|
128
114
|
- jpawlyn@gmail.com
|
129
115
|
executables: []
|
@@ -147,7 +133,6 @@ homepage: https://github.com/jpawlyn/similar_models
|
|
147
133
|
licenses:
|
148
134
|
- MIT
|
149
135
|
metadata: {}
|
150
|
-
post_install_message:
|
151
136
|
rdoc_options: []
|
152
137
|
require_paths:
|
153
138
|
- lib
|
@@ -155,18 +140,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
155
140
|
requirements:
|
156
141
|
- - ">="
|
157
142
|
- !ruby/object:Gem::Version
|
158
|
-
version: '
|
143
|
+
version: '3.1'
|
159
144
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
145
|
requirements:
|
161
146
|
- - ">="
|
162
147
|
- !ruby/object:Gem::Version
|
163
148
|
version: '0'
|
164
149
|
requirements: []
|
165
|
-
|
166
|
-
rubygems_version: 2.5.2
|
167
|
-
signing_key:
|
150
|
+
rubygems_version: 3.6.5
|
168
151
|
specification_version: 4
|
169
|
-
summary: Returns models that have
|
152
|
+
summary: Returns models that have associated models in common ordered by most in common
|
153
|
+
first
|
170
154
|
test_files:
|
171
155
|
- spec/post_spec.rb
|
172
156
|
- spec/spec_helper.rb
|