Skip to main content

Overview

The FormTemplate model represents a PDF form template that can be used for inspections. It stores the original PDF file, its structure, and manages relationships with inspections and form fills.

Database Schema

Attributes

id
integer
required
Primary key
name
string
Name of the form template
original_filename
string
Original filename of the uploaded PDF
file_path
string
Legacy file path (deprecated - use original_file attachment instead)
file_type
string
Type of the form file (e.g., “PDF”)
form_structure
text
JSON structure defining the form fields and their properties
system_category
string
System category for the form template (e.g., “Fire Protection”, “Sprinkler”)
created_at
datetime
Timestamp when the template was created
updated_at
datetime
Timestamp when the template was last updated

Associations

Has Many

inspections
has_many
Inspections using this templateDependent: restrict_with_error - Cannot delete template if inspections exist
template = FormTemplate.find(1)
template.inspections # => [#<Inspection...>, ...]
form_fills
has_many
Form fills based on this templateDependent: destroy - Deletes all form fills when template is deleted
template = FormTemplate.find(1)
template.form_fills # => [#<FormFill...>, ...]

Has One Attached

original_file
active_storage
The original PDF file uploaded for this templateValidation: Must be present
template = FormTemplate.find(1)
template.original_file.attached? # => true

Has and Belongs to Many

interval_categories
habtm
Interval categories associated with this template (e.g., monthly, quarterly, annual)
template = FormTemplate.find(1)
template.interval_categories # => [#<IntervalCategory...>, ...]

Validations

validates :original_file, presence: true
Note: Additional validations for name, file_type, and form_structure are commented out in the source but may be enforced at the application level.

Callbacks

Before Update

update_associated_form_fills
callback
Automatically updates the form_structure of all associated form fills when the template’s structure changes.Trigger: When form_structure is modifiedImplementation:
before_update :update_associated_form_fills, if: :form_structure_changed?
This ensures all existing form fills stay synchronized with template updates.

Public Methods

file_path

file_path
method
Returns the URL path for the attached original file.Returns: String or nilExample:
template = FormTemplate.find(1)
template.file_path
# => "/rails/active_storage/blobs/.../template.pdf"
Implementation:
def file_path
  if original_file.attached?
    Rails.application.routes.url_helpers.rails_blob_path(original_file, only_path: true)
  end
end

Usage Examples

Creating a New Template

template = FormTemplate.new(
  name: "Monthly Inspection Form",
  file_type: "PDF",
  system_category: "Fire Protection",
  form_structure: {
    fields: [
      { name: "inspector_name", type: "Text" },
      { name: "inspection_date", type: "Date" }
    ]
  }.to_json
)

template.original_file.attach(
  io: File.open('path/to/form.pdf'),
  filename: 'inspection_form.pdf',
  content_type: 'application/pdf'
)

template.save!

Updating Template Structure

template = FormTemplate.find(1)

# Update the form structure
template.update!(
  form_structure: new_structure.to_json
)

# All associated form_fills will automatically receive the new structure
template.form_fills.each do |form_fill|
  puts form_fill.form_structure # => Updated structure
end
template = FormTemplate.find(1)

# Get all inspections using this template
inspections = template.inspections

# Get all form fills
form_fills = template.form_fills

# Get interval categories
intervals = template.interval_categories

# Access the original file
if template.original_file.attached?
  url = template.file_path
  filename = template.original_file.filename
  content_type = template.original_file.content_type
end
  • FormFill - Individual form instances based on this template
  • Inspection - Inspections using this template

Build docs developers (and LLMs) love