Overview
The Deficiency model represents a unique deficiency type that can be identified during inspections. It maintains a catalog of standardized deficiency names for consistent reporting across inspections.
Database Schema
Attributes
Name of the deficiencyIndexed: Unique index for fast lookups and uniqueness enforcementValidation: Must be present and unique (case-insensitive)Examples:
- “Leaking valve”
- “Missing sprinkler head”
- “Corroded pipe”
- “Obstructed access”
Timestamp when the deficiency was created
Timestamp when the deficiency was last updated
Validations
validates :name, presence: true, uniqueness: { case_sensitive: false }
Validation Details
Presence: Must not be blankUniqueness: Must be unique across all deficiencies (case-insensitive)Examples:# Valid
Deficiency.create!(name: "Leaking Valve")
# Invalid - duplicate (case-insensitive)
Deficiency.create!(name: "leaking valve")
# => ActiveRecord::RecordInvalid: Name has already been taken
# Invalid - blank
Deficiency.create!(name: "")
# => ActiveRecord::RecordInvalid: Name can't be blank
Database Indexes
index ["name"], unique: true
The unique index on the name column ensures:
- Fast lookups by deficiency name
- Database-level enforcement of uniqueness
- Efficient queries when searching for specific deficiencies
Usage Examples
Creating Deficiencies
# Create a new deficiency
deficiency = Deficiency.create!(
name: "Leaking Valve"
)
# Create multiple deficiencies
deficiency_names = [
"Missing Sprinkler Head",
"Corroded Pipe",
"Obstructed Access",
"Damaged Valve Wheel",
"Missing Signage"
]
deficiency_names.each do |name|
Deficiency.create!(name: name)
end
Querying Deficiencies
# Find by name (case-insensitive)
deficiency = Deficiency.find_by("LOWER(name) = ?", "leaking valve".downcase)
# Get all deficiencies
all_deficiencies = Deficiency.all
# Search for deficiencies containing a keyword
valve_deficiencies = Deficiency.where("name ILIKE ?", "%valve%")
# Get deficiencies alphabetically
sorted = Deficiency.order(:name)
Using with Inspections
# In an inspection form fill, deficiencies are stored as data
form_fill = FormFill.find(1)
# Get deficiencies from the form fill
deficiencies = form_fill.get_deficiencies_for_processing
deficiencies.each do |def_data|
# Check if this deficiency type exists in the catalog
deficiency = Deficiency.find_or_create_by!(
name: def_data["value"]
)
# Process the deficiency
puts "Found: #{deficiency.name}"
puts "Item: #{def_data['Item']}"
puts "Comment: #{def_data['comment_value']}"
end
Managing the Deficiency Catalog
# Add a new deficiency to the catalog
def add_deficiency(name)
Deficiency.find_or_create_by!(name: name)
rescue ActiveRecord::RecordInvalid => e
puts "Error: #{e.message}"
end
# Update a deficiency name
deficiency = Deficiency.find_by(name: "Old Name")
deficiency.update!(name: "New Name")
# Remove a deficiency from the catalog
deficiency = Deficiency.find_by(name: "Obsolete Deficiency")
deficiency.destroy!
Seeding Common Deficiencies
# db/seeds.rb or migration
common_deficiencies = [
# Valve Issues
"Leaking valve",
"Stuck valve",
"Missing valve handle",
"Damaged valve wheel",
"Valve not accessible",
# Sprinkler Issues
"Missing sprinkler head",
"Damaged sprinkler head",
"Painted sprinkler head",
"Wrong temperature rating",
"Corroded sprinkler head",
# Pipe Issues
"Leaking pipe",
"Corroded pipe",
"Damaged pipe hanger",
"Missing pipe support",
"Exposed pipe threads",
# Access and Safety
"Obstructed access",
"Missing signage",
"Inadequate clearance",
"Locked access",
# System Issues
"Low water pressure",
"System needs testing",
"Gauge needs replacement",
"Missing inspection tag"
]
common_deficiencies.each do |name|
Deficiency.find_or_create_by!(name: name)
end
puts "Created #{Deficiency.count} deficiencies"
Reporting and Analytics
# This example assumes a relationship between Deficiency and inspection data
# (which may be implemented in your application logic)
# Get deficiency statistics across all inspections
def deficiency_report
deficiencies = {}
# Collect all deficiencies from form fills
FormFill.find_each do |form_fill|
form_fill.get_deficiencies_for_processing.each do |def_data|
name = def_data["value"]
next if name.blank?
deficiencies[name] ||= 0
deficiencies[name] += 1
end
end
# Sort by frequency
deficiencies.sort_by { |name, count| -count }.to_h
end
# Example output:
report = deficiency_report
# => {
# "Leaking valve" => 45,
# "Missing sprinkler head" => 23,
# "Corroded pipe" => 18,
# ...
# }
Best Practices
Standardization
# Always use consistent naming
class Deficiency < ApplicationRecord
before_validation :normalize_name
private
def normalize_name
self.name = name.strip.titleize if name.present?
end
end
# Usage:
Deficiency.create!(name: "leaking VALVE")
# Stored as: "Leaking Valve"
Finding or Creating
# Use find_or_create_by to avoid duplicates
def record_deficiency(name)
Deficiency.find_or_create_by!(name: name.strip.titleize)
end
# Usage in inspection processing
deficiency_name = "leaking valve"
deficiency = record_deficiency(deficiency_name)
Validation Before Save
# Check if deficiency exists before creating
def add_if_new(name)
return if Deficiency.exists?(name: name)
Deficiency.create!(name: name)
end
Integration with Inspections
While the Deficiency model doesn’t have direct associations with inspections in the current schema, it serves as a reference catalog. Actual deficiency instances are stored in the FormFill data:
# In FormFill
form_fill = FormFill.find(1)
# Get deficiencies
deficiencies = form_fill.get_deficiencies_for_processing
# => [
# {
# "name" => "valve_deficiency",
# "value" => "Leaking Valve", # References Deficiency.name
# "comment_value" => "Requires immediate repair",
# "Item" => "Main Control Valve",
# "Riser" => "A-1",
# "C" => "Critical",
# "D" => "2024-01-20"
# }
# ]
# Validate against catalog
deficiencies.each do |def_data|
deficiency_type = Deficiency.find_by(name: def_data["value"])
if deficiency_type
puts "Known deficiency: #{deficiency_type.name}"
else
puts "New deficiency type: #{def_data['value']}"
# Optionally add to catalog
Deficiency.create!(name: def_data["value"])
end
end
- FormFill - Stores actual deficiency instances in the data column
- Inspection - Inspections that may contain deficiencies