Skip to content

Commit 6a93d10

Browse files
committed
fix: resolve N+1, missing data, and silent query failures in Blueprinter migration
- Eager load srg_rule for satisfies/satisfied_by to prevent N+1 in SatisfactionBlueprint - Add :related view to ComponentBlueprint with project data for RelatedRulesModal - Add :released and :updated_at to available_components select for ComponentBlueprint :index - Use LIKE query for CCI-000366 lookup to handle multi-value ident column - Build references association in create_or_duplicate to match prior from_mapping behavior Signed-off-by: Will <will@dower.dev>
1 parent 602d96f commit 6a93d10

File tree

3 files changed

+19
-5
lines changed

3 files changed

+19
-5
lines changed

app/blueprints/component_blueprint.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ class ComponentBlueprint < Blueprinter::Base
3333
fields :updated_at, :released
3434
end
3535

36+
# === Related view: related_rules parents (includes project for display name) ===
37+
view :related do
38+
fields :updated_at, :released
39+
40+
field :project do |component, _options|
41+
ProjectBlueprint.render_as_hash(component.project)
42+
end
43+
end
44+
3645
# === Show view: non-member read-only ===
3746
view :show do
3847
fields :title, :description, :admin_name, :admin_email, :released, :updated_at

app/controllers/rules_controller.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ class RulesController < ApplicationController
1616

1717
def index
1818
@rules = @component.rules.eager_load(:reviews, :disa_rule_descriptions, :rule_descriptions, :checks,
19-
:additional_answers, :satisfies, :satisfied_by,
19+
:additional_answers,
20+
{ satisfies: :srg_rule, satisfied_by: :srg_rule },
2021
srg_rule: %i[disa_rule_descriptions rule_descriptions checks])
2122
@rules_json = RuleBlueprint.render(@rules, view: :editor)
2223
@component_json = ComponentBlueprint.render(@component, view: :editor)
@@ -53,7 +54,9 @@ def related_rules
5354
stig_rules = StigRule.where(srg_id: srg_id).eager_load(:disa_rule_descriptions, :checks, :stig)
5455
rules = rules.filter { |r| r.component.all_users.include?(current_user) } unless current_user.admin?
5556
stig_parents = StigBlueprint.render_as_hash(stig_rules.map(&:stig).uniq, view: :index)
56-
component_parents = ComponentBlueprint.render_as_hash(rules.map(&:component).uniq, view: :index)
57+
components = rules.map(&:component).uniq
58+
ActiveRecord::Associations::Preloader.new(records: components, associations: :project).call
59+
component_parents = ComponentBlueprint.render_as_hash(components, view: :related)
5760
parents = (stig_parents + component_parents)
5861

5962
all_rules = StigRuleBlueprint.render_as_hash(stig_rules) +
@@ -187,8 +190,8 @@ def create_or_duplicate
187190
new_rule
188191
elsif authorize_admin_project.nil?
189192
srg = SecurityRequirementsGuide.find_by(id: @component.security_requirements_guide_id)
190-
db_srg_rule = srg.srg_rules.eager_load(:disa_rule_descriptions, :checks, :rule_descriptions)
191-
.find_by(ident: 'CCI-000366')
193+
db_srg_rule = srg.srg_rules.eager_load(:disa_rule_descriptions, :checks, :rule_descriptions, :references)
194+
.where('ident LIKE ?', '%CCI-000366%').first
192195

193196
rule = Rule.new(
194197
component: @component,
@@ -207,6 +210,7 @@ def create_or_duplicate
207210
)
208211
rule.disa_rule_descriptions.build(db_srg_rule.disa_rule_descriptions.map { |d| d.attributes.except('id', 'base_rule_id') }) if db_srg_rule&.disa_rule_descriptions&.any?
209212
rule.checks.build(db_srg_rule.checks.map { |c| c.attributes.except('id', 'base_rule_id') }) if db_srg_rule&.checks&.any?
213+
rule.references.build(db_srg_rule.references.map { |r| r.attributes.except('id', 'base_rule_id') }) if db_srg_rule&.references&.any?
210214
rule.audits.build(Audited.audit_class.create_initial_rule_audit_from_mapping(@component.id))
211215

212216
rule

app/models/project.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ def available_components
8585
reject_component_ids = components.pluck(:id, :component_id).flatten.compact
8686
# Assumption that released components are publicly available within vulcan
8787
Component.where(released: true).where.not(id: reject_component_ids)
88-
.select(:id, :name, :prefix, :version, :release, :project_id, :security_requirements_guide_id)
88+
.select(:id, :name, :prefix, :version, :release, :project_id,
89+
:security_requirements_guide_id, :released, :updated_at)
8990
end
9091
end

0 commit comments

Comments
 (0)