similar_models 0.4.0 → 0.4.1
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 -1
- data/lib/similar_models/version.rb +1 -1
- data/lib/similar_models.rb +24 -3
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1512f7d1b0d895cc90aa6bf3357e8379aac8f57848de01f2a0d05816107e8936
|
4
|
+
data.tar.gz: 5001875c74fce6ba9bfbce5af20424742c87564d07a7b16393f953ada0b59cfa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76f8b14e266fc0cf9063c19d5a39c6ce346b05539a450ab100e13e0440b7ea6293b4c02c1250f1e9a68a37fb9a7d952b3b6380bf3ea64bdd5c01984848d001a2
|
7
|
+
data.tar.gz: 51e379dc7d45bd905d0a52d791b8cd9a869ee5fe285848ced7ff3a579e4758ccb677095faadd5b55d812055acc87b4c0dbdc260e95aaa1ef8b51fa983d50b32b
|
data/README.md
CHANGED
@@ -4,9 +4,11 @@ Adds a `similar_#{model_name.plural}` instance and class method to an active rec
|
|
4
4
|
|
5
5
|
The instance method returns models that have associated models in common ordered by most in common first.
|
6
6
|
|
7
|
+
A practical example for this could be linking to related blog posts when rendering an individual blog post. Related blog posts could be related by author, tag or author and tag combined.
|
8
|
+
|
7
9
|
The class method returns models ordered by most associated models in common.
|
8
10
|
|
9
|
-
If the commonality count is the same then a second order clause of `created_at` if present
|
11
|
+
If the commonality count is the same then a second order clause of `created_at` takes precedence if present.
|
10
12
|
|
11
13
|
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).
|
12
14
|
|
data/lib/similar_models.rb
CHANGED
@@ -39,9 +39,30 @@ module SimilarModels
|
|
39
39
|
# INNER JOIN author_posts ON author_posts.post_id = posts.alt_id
|
40
40
|
# WHERE "posts"."alt_id" != ? AND
|
41
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
|
42
|
+
# GROUP BY posts.alt_id
|
43
43
|
# ORDER BY similar_posts_commonality_count DESC, created_at DESC
|
44
44
|
#
|
45
|
+
# example sql query for two many to many associations:
|
46
|
+
#
|
47
|
+
# SELECT posts.*, count(posts.alt_id) AS similar_posts_by_author_and_tag_commonality_count
|
48
|
+
# FROM (
|
49
|
+
# (SELECT "posts".* FROM "posts"
|
50
|
+
# INNER JOIN author_posts ON author_posts.post_id = posts.alt_id
|
51
|
+
# WHERE (author_posts.author_id IN
|
52
|
+
# (select author_posts.author_id from author_posts where author_posts.post_id = ?)
|
53
|
+
# )
|
54
|
+
# )
|
55
|
+
# UNION ALL
|
56
|
+
# (SELECT "posts".* FROM "posts"
|
57
|
+
# INNER JOIN posts_tags ON posts_tags.post_id = posts.alt_id
|
58
|
+
# WHERE (posts_tags.tag_id IN
|
59
|
+
# (select posts_tags.tag_id from posts_tags where posts_tags.post_id = ?)
|
60
|
+
# )
|
61
|
+
# )
|
62
|
+
# )
|
63
|
+
# AS posts WHERE "posts"."alt_id" != ? GROUP BY posts.alt_id, posts.created_at, posts.updated_at
|
64
|
+
# ORDER BY similar_posts_by_author_and_tag_commonality_count DESC, created_at DESC
|
65
|
+
#
|
45
66
|
define_method as do
|
46
67
|
table_name = self.class.table_name
|
47
68
|
primary_key = self.class.primary_key
|
@@ -63,12 +84,12 @@ module SimilarModels
|
|
63
84
|
order_clause += ", created_at DESC" if self.class.column_names.include?('created_at')
|
64
85
|
scope = self.class.select("#{table_name}.*, count(#{primary_key_ref}) AS #{as}_commonality_count").
|
65
86
|
where.not(primary_key => self.id).order(order_clause)
|
66
|
-
group_by_clause = self.class.column_names.map { |column| "#{table_name}.#{column}"}.join(', ')
|
67
87
|
|
68
88
|
# if there is only one many-to-many association no need to use UNION sql syntax
|
69
89
|
if association_scopes.one?
|
70
|
-
scope.merge(association_scopes.first).group(
|
90
|
+
scope.merge(association_scopes.first).group(primary_key_ref)
|
71
91
|
else
|
92
|
+
group_by_clause = self.class.column_names.map { |column| "#{table_name}.#{column}"}.join(', ')
|
72
93
|
scope.from("((#{association_scopes.map(&:to_sql).join(') UNION ALL (')})) AS #{table_name}").group(group_by_clause)
|
73
94
|
end
|
74
95
|
end
|