Skip to content

Commit 9a97004

Browse files
committed
[WIP] feat(reversibility): add component resource cache for filtering resource side records + add followers to bundle
1 parent 3d18e4e commit 9a97004

3 files changed

Lines changed: 89 additions & 16 deletions

File tree

‎app/services/decidim/content/csv_bundler.rb‎

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,7 @@ def bundle
117117
include_if: ->(parent) { parent&.manifest_name == "debates" },
118118
serializer: Decidim::Content::DebateSerializer,
119119
collection: lambda { |parent|
120-
Decidim::Debates::Debate
121-
.not_hidden
122-
.where(component: parent)
123-
.includes(:category)
120+
debates_for_component(parent).includes(:category)
124121
}
125122
},
126123
{
@@ -156,9 +153,15 @@ def bundle
156153
},
157154
{
158155
path: "endorsements",
159-
include_if: ->(parent) { endorsable_component?(parent&.manifest_name) && parent&.manifest_name == "proposals" },
156+
include_if: ->(parent) { endorsable_component?(parent&.manifest_name) && %w(proposals debates).include?(parent&.manifest_name) },
160157
serializer: Decidim::Content::EndorsementSerializer,
161158
collection: ->(parent) { endorsements_for_component(parent) }
159+
},
160+
{
161+
path: "followers",
162+
include_if: ->(parent) { followable_component?(parent&.manifest_name) && %w(proposals debates).include?(parent&.manifest_name) },
163+
serializer: Decidim::Content::FollowerSerializer,
164+
collection: ->(parent) { followers_for_component(parent) }
162165
}
163166
]
164167
}
@@ -312,13 +315,6 @@ def participatory_process_users(participatory_process)
312315
private_users = participatory_process.users.select(:decidim_user_id).reorder("decidim_user_id").to_a
313316
(users_with_roles + private_users).uniq(&:decidim_user_id).map { |o| o.attributes.compact.symbolize_keys.merge(role: o[:role] || "private_user") }
314317
end
315-
316-
def proposals_for_component(component)
317-
Decidim::Proposals::Proposal
318-
.published
319-
.not_hidden
320-
.where(component:)
321-
end
322318
end
323319
end
324320
end

‎lib/concerns/decidim/content/component_tools.rb‎

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,26 @@ module Content
77
module ComponentTools
88
extend ActiveSupport::Concern
99
included do
10+
def component_resource_cache
11+
@component_resource_cache ||= Hash.new { |h, k| h[k] = h.dup.clear }
12+
end
13+
14+
def component_resource_cache_set(component:, resource_class:, query:, force: false)
15+
if force || component_resource_cache[component.id][resource_class.name].blank?
16+
component_resource_cache[component.id][resource_class.name] = query
17+
else
18+
resource_class.none
19+
end
20+
end
21+
22+
def component_resource_cache_get(component:, resource_class:)
23+
component_resource_cache[component.id][resource_class.name]
24+
end
25+
26+
def component_resource_cache_exists?(component:, resource_class:)
27+
component_resource_cache[component.id][resource_class.name].present?
28+
end
29+
1030
def component_resource_manifests(manifest_name)
1131
return [] if manifest_name.blank?
1232

@@ -60,14 +80,21 @@ def comments_for_resource(resource_class, component)
6080
gateway_resources = gateway_reflection.try(:options)&.[](:class_name)&.constantize&.where(component:)
6181
root_commentable = gateway_resources.present? ? resource_class.where(through => gateway_resources) : resource_class.none
6282
end
83+
84+
if component_resource_cache_exists?(component:, resource_class:)
85+
cached_ids = component_resource_cache_get(component:, resource_class:).pluck(:id)
86+
root_commentable = root_commentable.where(id: cached_ids)
87+
end
88+
6389
if root_commentable.present?
6490
return Decidim::Comments::Comment
6591
.not_deleted
6692
.not_hidden
6793
.where(root_commentable:)
6894
end
6995
end
70-
Rails.logger.warn "Decidim::Content::ComponentTools.comments_for_resource (concerns) : Unable to fetch comments for #{resource_class} with component association."
96+
Rails.logger.warn "Decidim::Content::ComponentTools.comments_for_resource (concerns) : No comments found for #{resource_class} with component association."
97+
Rails.logger.warn "-- cached query was involved with #{cached_ids.size} records" if component_resource_cache_exists?(component:, resource_class:)
7198
Decidim::Comments::Comment.none
7299
end
73100
# rubocop:enable Metrics/CyclomaticComplexity
@@ -81,11 +108,56 @@ def endorsements_for_component(component)
81108

82109
def endorsements_for_resource(resource_class, component)
83110
endorsable_resources = resource_class.where(component:)
111+
if component_resource_cache_exists?(component:, resource_class:)
112+
cached_ids = component_resource_cache_get(component:, resource_class:).pluck(:id)
113+
endorsable_resources = endorsable_resources.where(id: cached_ids)
114+
end
84115
return Decidim::Endorsement.where(resource: endorsable_resources) if endorsable_resources.present?
85116

86-
Rails.logger.warn "Decidim::Content::ComponentTools.endorsements_for_resource (concerns) : Unable to fetch endorsements for #{resource_class} with component association."
117+
Rails.logger.warn "Decidim::Content::ComponentTools.endorsements_for_resource (concerns) : No endorsements found for #{resource_class} with component association."
118+
Rails.logger.warn "-- cached query was involved with #{cached_ids.size} records" if component_resource_cache_exists?(component:, resource_class:)
87119
Decidim::Endorsement.none
88120
end
121+
122+
def followers_for_component(component)
123+
component_resource_manifests_including_trait(component&.manifest_name, Decidim::Followable).each.with_object([]) do |manifest, results|
124+
results.concat(followers_for_resource(manifest.model_class_name.constantize, component)) if manifest.model_class_name.present?
125+
end
126+
end
127+
128+
def followers_for_resource(resource_class, component)
129+
followable_resources = resource_class.where(component:)
130+
if component_resource_cache_exists?(component:, resource_class:)
131+
cached_ids = component_resource_cache_get(component:, resource_class:).pluck(:id)
132+
followable_resources = followable_resources.where(id: cached_ids)
133+
end
134+
return Decidim::Follow.where(followable: followable_resources) if followable_resources.present?
135+
136+
Rails.logger.warn "Decidim::Content::ComponentTools.followers_for_resource (concerns) : No followers found for #{resource_class} with component association."
137+
Rails.logger.warn "-- cached query was involved with #{cached_ids.size} records" if component_resource_cache_exists?(component:, resource_class:)
138+
Decidim::Follow.none
139+
end
140+
141+
def proposals_for_component(component)
142+
component_resource_cache_set(
143+
component:,
144+
resource_class: Decidim::Proposals::Proposal,
145+
query: Decidim::Proposals::Proposal
146+
.published
147+
.not_hidden
148+
.where(component:)
149+
)
150+
end
151+
152+
def debates_for_component(component)
153+
component_resource_cache_set(
154+
component:,
155+
resource_class: Decidim::Debates::Debate,
156+
query: Decidim::Debates::Debate
157+
.not_hidden
158+
.where(component:)
159+
)
160+
end
89161
end
90162
end
91163
end

‎lib/concerns/decidim/content/uid_tools.rb‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@ def locate_resource_by_uid(uid)
1919
end
2020

2121
def polymorphic_uid(resource, key)
22-
return unless key.present? && resource.respond_to?(key.to_sym)
22+
return if key.blank?
2323

24-
uid(resource.try("#{key}_type".to_sym)&.safe_constantize&.new(id: resource.try("#{key}_id".to_sym)))
24+
type_attribute = "#{key}_type".to_sym
25+
id_attribute = "#{key}_id".to_sym
26+
return unless resource.respond_to?(type_attribute) && resource.respond_to?(id_attribute)
27+
28+
# Rails.logger.debug { "polymorphic_uid: resource=#{resource.class.name} key=#{key} type=#{resource.try(type_attribute)} id=#{resource.try(id_attribute)}" }
29+
uid(resource.try(type_attribute)&.safe_constantize&.new(id: resource.try(id_attribute)&.to_i))
2530
end
2631
end
2732
end

0 commit comments

Comments
 (0)