similar_models 0.1.0 → 0.2.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 +4 -4
- data/README.md +3 -3
- data/lib/similar_models/version.rb +1 -1
- data/lib/similar_models.rb +11 -12
- data/similar_models.gemspec +4 -4
- data/spec/spec_helper.rb +11 -1
- data/spec/support/schema.rb +1 -1
- metadata +10 -11
- data/.rspec +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad504d7a2e4aff75dc1c3ff6d48162110aaedcad
|
4
|
+
data.tar.gz: 38cbf0ecea5b020f118845b893d59ab7bdb508c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aebcd2acdddd464feedfc604300daf67add8022fa18920305f2849a31489f1dc8534ffe6eb21e02061be09ac89984194347f2997e496cd031a997b6988388864
|
7
|
+
data.tar.gz: aacfe230c5415df95ef1f4253cb837b53d559b5e770ceafaea9794611f3733fdb9219886c3ce6ae4053a70cc40f1531babd464483d22f69dd870340183f2e2ba
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Adds a `similar_{model name plural}` method to an active record model, but can be set to any name using `as: {method name}`. It returns the most similar models of the same class based on associated models in common.
|
4
4
|
|
5
|
-
The association(s) have to be many to many, so either habtm or
|
5
|
+
The association(s) have to be many to many, so either [habtm](http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association) or [has_many :through](http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association).
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
@@ -28,8 +28,8 @@ Post example
|
|
28
28
|
has_and_belongs_to_many :tags
|
29
29
|
|
30
30
|
has_similar_models :authors
|
31
|
-
has_similar_models :tags, as: :
|
32
|
-
has_similar_models :authors, :tags, as: :
|
31
|
+
has_similar_models :tags, as: :similar_posts_by_tag
|
32
|
+
has_similar_models :authors, :tags, as: :similar_posts_by_author_and_tag
|
33
33
|
end
|
34
34
|
|
35
35
|
class Tag < ActiveRecord::Base
|
data/lib/similar_models.rb
CHANGED
@@ -8,31 +8,30 @@ module SimilarModels
|
|
8
8
|
# defaults to 'def similar_{model name}'
|
9
9
|
define_method as do
|
10
10
|
table_name = self.class.table_name
|
11
|
+
primary_key = self.class.primary_key
|
12
|
+
primary_key_ref = "#{table_name}.#{primary_key}"
|
11
13
|
association_scopes = []
|
12
14
|
|
13
15
|
many_to_many_associations.each do |many_to_many_association|
|
14
16
|
assocation = self.class.reflect_on_association(many_to_many_association)
|
15
17
|
join_table, foreign_key, association_foreign_key = self.class.join_table_values(assocation)
|
16
18
|
|
17
|
-
association_scopes << self.class.where(
|
18
|
-
"
|
19
|
-
|
20
|
-
|
19
|
+
association_scopes << self.class.where(
|
20
|
+
"#{join_table}.#{association_foreign_key} IN \
|
21
|
+
(select #{join_table}.#{association_foreign_key} from #{join_table} \
|
22
|
+
where #{join_table}.#{foreign_key} = :foreign_key)", foreign_key: self.id
|
23
|
+
).joins("INNER JOIN #{join_table} ON #{join_table}.#{foreign_key} = #{primary_key_ref}")
|
21
24
|
end
|
22
25
|
|
23
|
-
scope = self.class.select("#{table_name}.*, count(#{
|
24
|
-
where.not(
|
25
|
-
group_by_clause =
|
26
|
+
scope = self.class.select("#{table_name}.*, count(#{primary_key_ref}) AS #{as}_model_count").
|
27
|
+
where.not(primary_key => self.id).order("#{as}_model_count DESC")
|
28
|
+
group_by_clause = primary_key
|
26
29
|
|
27
30
|
# if there is only one many-to-many association no need to use UNION sql syntax
|
28
31
|
if association_scopes.one?
|
29
32
|
scope.merge(association_scopes.first).group(group_by_clause)
|
30
33
|
else
|
31
|
-
|
32
|
-
# http://dba.stackexchange.com/questions/88988/postgres-error-column-must-appear-in-the-group-by-clause-or-be-used-in-an-aggre
|
33
|
-
if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
34
|
-
group_by_clause = self.class.column_names.join(', ')
|
35
|
-
end
|
34
|
+
group_by_clause = self.class.column_names.join(', ')
|
36
35
|
|
37
36
|
# see http://blog.ubersense.com/2013/09/27/tech-talk-unioning-scoped-queries-in-rails/
|
38
37
|
scope.from("((#{association_scopes.map(&:to_sql).join(') UNION ALL (')})) AS #{table_name}").group(group_by_clause)
|
data/similar_models.gemspec
CHANGED
@@ -19,12 +19,12 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.required_ruby_version = '>= 2.1'
|
22
|
-
spec.add_runtime_dependency 'activerecord', '
|
23
|
-
spec.add_development_dependency 'bundler', '~> 1.
|
22
|
+
spec.add_runtime_dependency 'activerecord', '>= 4.2'
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
24
24
|
spec.add_development_dependency 'rspec', '~> 3.5'
|
25
25
|
spec.add_development_dependency 'database_cleaner', '~>1.5'
|
26
26
|
spec.add_development_dependency 'sqlite3', '~>1.3'
|
27
|
-
spec.add_development_dependency 'mysql2', '~>0.
|
28
|
-
spec.add_development_dependency 'pg', '~>0
|
27
|
+
spec.add_development_dependency 'mysql2', '~>0.5'
|
28
|
+
spec.add_development_dependency 'pg', '~>1.0'
|
29
29
|
spec.add_development_dependency 'byebug', '~>9.0'
|
30
30
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
require 'active_record'
|
9
9
|
|
10
10
|
ActiveRecord::Base.establish_connection adapter: 'postgresql', database: 'similar_models'
|
11
|
-
# ActiveRecord::Base.establish_connection adapter: 'mysql2', database: 'similar_models'
|
11
|
+
# ActiveRecord::Base.establish_connection adapter: 'mysql2', database: 'similar_models', username: 'test'
|
12
12
|
# ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
|
13
13
|
load 'support/schema.rb'
|
14
14
|
|
@@ -24,6 +24,16 @@ RSpec.configure do |config|
|
|
24
24
|
config.run_all_when_everything_filtered = true
|
25
25
|
config.filter_run :focus
|
26
26
|
|
27
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
28
|
+
# file, and it's useful to allow more verbose output when running an
|
29
|
+
# individual spec file.
|
30
|
+
if config.files_to_run.one?
|
31
|
+
# Use the documentation formatter for detailed output,
|
32
|
+
# unless a formatter has already been configured
|
33
|
+
# (e.g. via a command-line flag).
|
34
|
+
config.default_formatter = 'doc'
|
35
|
+
end
|
36
|
+
|
27
37
|
# Run specs in random order to surface order dependencies. If you find an
|
28
38
|
# order dependency and want to debug it, you can fix the order by providing
|
29
39
|
# the seed, which is printed after each run.
|
data/spec/support/schema.rb
CHANGED
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: similar_models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
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: 2018-05-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '4.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '4.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.16'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.16'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,28 +86,28 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0.
|
89
|
+
version: '0.5'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0.
|
96
|
+
version: '0.5'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: pg
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0
|
103
|
+
version: '1.0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '0
|
110
|
+
version: '1.0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: byebug
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -131,7 +131,6 @@ extensions: []
|
|
131
131
|
extra_rdoc_files: []
|
132
132
|
files:
|
133
133
|
- ".gitignore"
|
134
|
-
- ".rspec"
|
135
134
|
- ".ruby-version"
|
136
135
|
- Gemfile
|
137
136
|
- LICENSE.txt
|
data/.rspec
DELETED