Skip to content

Commit

Permalink
Implement LiquidCachedAssigns
Browse files Browse the repository at this point in the history
  • Loading branch information
aapomm committed Jun 14, 2024
1 parent 768ce3b commit bad84b1
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 49 deletions.
2 changes: 1 addition & 1 deletion app/controllers/concerns/liquid_enabled_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ def project_assigns
project = Project.find(params[:project_id])
authorize! :use, project

LiquidAssignsService.new(project: project, text: params[:text]).assigns
LiquidAssignsService.new(project: project).assigns
end
end
51 changes: 3 additions & 48 deletions app/services/liquid_assigns_service.rb
Original file line number Diff line number Diff line change
@@ -1,61 +1,16 @@
class LiquidAssignsService
AVAILABLE_PROJECT_ASSIGNS = %w{ evidences issues nodes notes tags }.freeze
attr_accessor :project

attr_accessor :project, :text

def initialize(project:, text: nil)
def initialize(project:)
@project = project
@text = text
end

def assigns
result = project_assigns
result.merge!(assigns_pro) if defined?(Dradis::Pro)
result
LiquidCachedAssigns.new(project: project)
end

private

def assigns_pro
end

# This method uses Liquid::VariableLookup to find all liquid variables from
# a given text. We use the list to know which project assign we need.
def assigns_from_content
return AVAILABLE_PROJECT_ASSIGNS if text.nil?

variable_lookup = Liquid::VariableLookup.parse(text)
return (variable_lookup.lookups & AVAILABLE_PROJECT_ASSIGNS)
end

def cached_drops(records, record_type)
return [] if records.empty?

cache_key = "liquid-project-#{project.id}-#{record_type.pluralize}:#{records.maximum(:updated_at).to_i}-#{records.count}"
drop_class = "#{record_type.camelize}Drop".constantize

Rails.cache.fetch(cache_key) do
records.map { |record| drop_class.new(record) }
end
end

def project_assigns
project_assigns = { 'project' => ProjectDrop.new(project) }

assigns_from_content.each do |record_type|
records =
case record_type
when 'evidences'
project.evidence
when 'nodes'
project.nodes.user_nodes
else
project.send(record_type.to_sym)
end

project_assigns.merge!(record_type => cached_drops(records, record_type.singularize))
end

project_assigns
end
end
59 changes: 59 additions & 0 deletions app/services/liquid_cached_assigns.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
class LiquidCachedAssigns < Hash
AVAILABLE_PROJECT_ASSIGNS = %w{ evidences issues nodes notes project tags }.freeze

attr_accessor :assigns, :project

def initialize(project:)
@assigns = { 'project' => ProjectDrop.new(@project) }
@project = project
end

def [](record_type)
return unless AVAILABLE_PROJECT_ASSIGNS.include?(record_type)

if assigns[record_type]
assigns[record_type]
else
assigns[record_type] = cached_drops(record_type)
end
end

def inspect
assigns.inspect
end

def key?(msg)
AVAILABLE_PROJECT_ASSIGNS.include?(msg.to_s)
end

def respond_to?(msg)
return true if key?(msg)
super(msg)
end

private

def cached_drops(record_type)
records = project_records(record_type)

return [] if records.empty?

cache_key = ActiveSupport::Cache.expand_cache_key([project.id, records], 'liquid')
drop_class = "#{record_type.singularize.camelize}Drop".constantize

Rails.cache.fetch(cache_key) do
records.map { |record| drop_class.new(record) }
end
end

def project_records(record_type)
case record_type
when 'evidences'
project.evidence
when 'nodes'
project.nodes.user_nodes
else
project.send(record_type.to_sym)
end
end
end

0 comments on commit bad84b1

Please sign in to comment.