join_cache 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +3 -1
- data/VERSION +1 -1
- data/join_cache.gemspec +1 -1
- data/lib/join_cache.rb +43 -0
- metadata +2 -2
data/README.markdown
CHANGED
@@ -47,10 +47,12 @@ class Employee < ActiveRecord::Base
|
|
47
47
|
end
|
48
48
|
```
|
49
49
|
|
50
|
+
It also works with `has_many :through` associations!
|
51
|
+
|
50
52
|
## TODO
|
51
53
|
|
52
|
-
* [Support has_many :through](https://github.com/KevinBongart/join_cache/issues/1)
|
53
54
|
* [Support callbacks: after_add and after_remove](https://github.com/KevinBongart/join_cache/issues/2)
|
55
|
+
* [Add tests](https://github.com/KevinBongart/join_cache/issues/3)
|
54
56
|
|
55
57
|
[View the full list](https://github.com/KevinBongart/join_cache/issues)
|
56
58
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/join_cache.gemspec
CHANGED
data/lib/join_cache.rb
CHANGED
@@ -39,5 +39,48 @@ module JoinCache
|
|
39
39
|
association.klass.where(id: send(cached_ids_name))
|
40
40
|
end
|
41
41
|
end
|
42
|
+
|
43
|
+
has_many_through_associations = reflect_on_all_associations(:has_many).select do |association|
|
44
|
+
association.is_a?(ActiveRecord::Reflection::ThroughReflection)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Generates methods for faster retrieval of has_many :through associations
|
48
|
+
# by storing foreign keys in cache and avoiding large joins
|
49
|
+
#
|
50
|
+
# For example:
|
51
|
+
# class Physician < ActiveRecord::Base
|
52
|
+
# has_many :appointments
|
53
|
+
# has_many :patients, through: :appointments
|
54
|
+
# include JoinCache
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# Physician.first.cached_patient_ids
|
58
|
+
# => [4, 8, 15, 16, 23, 42]
|
59
|
+
#
|
60
|
+
# Physician.first.cached_patients
|
61
|
+
# => Patient.where(id: [4, 8, 15, 16, 23, 42])
|
62
|
+
#
|
63
|
+
has_many_through_associations.each do |association|
|
64
|
+
singular_name = association.name.to_s.singularize # patient
|
65
|
+
plural_name = association.plural_name # patients
|
66
|
+
cached_name = "cached_#{plural_name}" # cached_patients
|
67
|
+
cached_ids_name = "cached_#{singular_name}_ids" # cached_patient_ids
|
68
|
+
primary_key = self.name.foreign_key # employee_id
|
69
|
+
foreign_key = association.foreign_key # patient_id
|
70
|
+
join_table = association.options[:through] # appointments
|
71
|
+
join_model = join_table.to_s.classify.constantize # Appointment
|
72
|
+
|
73
|
+
# cached_patient_ids
|
74
|
+
define_method(cached_ids_name) do
|
75
|
+
Rails.cache.fetch("#{cache_key}/#{cached_ids_name}") do
|
76
|
+
join_model.where(primary_key => id).pluck(foreign_key.to_sym)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# cached_patients
|
81
|
+
define_method(cached_name) do
|
82
|
+
association.klass.where(id: send(cached_ids_name))
|
83
|
+
end
|
84
|
+
end
|
42
85
|
end
|
43
86
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: join_cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -109,7 +109,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
109
109
|
version: '0'
|
110
110
|
segments:
|
111
111
|
- 0
|
112
|
-
hash:
|
112
|
+
hash: 1146460858880032511
|
113
113
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
114
|
none: false
|
115
115
|
requirements:
|